/*
 * Copyright (C) 2010,2011  Paulo Cesar Pereira de Andrade.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Authors:
 *	Paulo Cesar Pereira de Andrade
 */

#include "exl.h"

#include <signal.h>

#if defined(__ppc__)
#  define check_int_divide_by_zero(n)					\
    do {								\
	if (unlikely((n) == 0))						\
	    ethread_kill(SIGFPE);					\
    } while (0)
#else
#  define check_int_divide_by_zero(n)		/**/
#endif

/*
 * Implementation
 */
#if !HAVE_C99_CPROJ
complex double
c99cproj(complex double dd)
{
    if (unlikely(isinf(real(dd)) || isinf(imag(dd)))) {
	complex double c;

	real(c) = INFINITY;
	imag(c) = copysign(0.0, imag(dd));

	return (c);
    }

    return (dd);
}
#endif

#if !HAVE_CLOG2
complex double
clog2(complex double dd)
{
    complex double	z;

    real(z) = ed_log2_d(ed_hypot_d_d(real(dd), imag(dd)));
    imag(z) = M_LOG2E * ed_atan2_d_d(imag(dd), real(dd));

    return (z);
}
#endif

#if !HAVE_CLOG10
complex double
clog10(complex double dd)
{
    complex double	z;

    real(z) = ed_log10_d(ed_hypot_d_d(real(dd), imag(dd)));
    imag(z) = M_LOG10E * ed_atan2_d_d(imag(dd), real(dd));

    return (z);
}
#endif

#if __WORDSIZE == 32
eint32_t
empz_fit_i(empz_t z)
{
    switch (z->_mp_size) {
	case 0: case 1: case -1: return (1);
	case 2: case -2:	 return (z->_mp_d[1] <= 0x7fffffff);
	default:		 return (0);
    }
}

eint32_t
empz_fit_u(empz_t z)
{
    switch (z->_mp_size) {
	case 0: case 1: case 2:	return (1);
	default:		return (0);
    }
}

eint32_t
empz_cmp_i(empz_t z, eint_t i)
{
    mp_size_t	n;
    mp_ptr	p;
    eint_t	v;

    p = z->_mp_d;
    n = z->_mp_size;
    /* z > 0 */
    if (n > 0) {
	/* i <= 0 || z > max_int */
	if (i <= 0 || n > 2)
	    return (1);
	v = p[0];
	if (n == 2) {
	    v |= (euint_t)p[1] << 32;
	    /* FIXME (?) integer objects can have the MININT value,
	     * due to the way add/sub check is done */
	    if (v == MININT)
		return (i == v ? 0 : 1);
	    if (v < 0)
		return (1);
	}
	return (v > i ? 1 : v < i ? -1 : 0);
    }
    /* z < 0 */
    else if (n < 0) {
	/* i >= 0 || z < min_int */
	if (i >= 0 || n < -2)
	    return (-1);
	v = p[0];
	if (n == -2) {
	    v |= (euint_t)p[1] << 32;
	    if (v == MININT)
		return (i == v ? 0 : -1);
	}
	v = -v;
	return (v > i ? 1 : v < i ? -1 : 0);
    }
    /* z == 0 */
    return (0 > i ? 1 : 0 < i ? -1 : 0);
}

eint32_t
empz_cmp_u(empz_t z, euint_t u)
{
    mp_size_t	n;
    mp_ptr	p;
    euint_t	v;

    p = z->_mp_d;
    n = z->_mp_size;
    /* z > 0 */
    if (n > 0) {
	/* z > max_uint */
	if (n > 2)
	    return (1);
	v = p[0];
	if (n == 2)
	    v |= (euint_t)p[1] << 32;
	return (v > u ? 1 : v < u ? -1 : 0);
    }
    /* z < 0 */
    else if (n < 0)
	return (-1);
    /* z == 0 */
    return (u ? -1 : 0);
}

eint_t
empz_get_i(empz_t z)
{
    mp_size_t	n;
    mp_ptr	p;
    eint_t	i;

    p = z->_mp_d;
    n = z->_mp_size;
    if (n > 0) {
	i = p[0];
	if (n > 1)	i |= (eint_t)p[1] << 32;
    }
    else if (n < 0) {
	i = p[0];
	if (n < -1)	i |= (eint_t)p[1] << 32;
	i = -i;
    }
    else
	i = 0;

    return (i);
}

void
empz_set_i(empz_t z, eint_t i)
{
    if (!emp_si_p(i)) {
	mpz_set_si(z, i >> 32);
	mpz_mul_2exp(z, z, 32);
	mpz_add_ui(z, z, i & 0xffffffff);
    }
    else
	mpz_set_si(z, i);
}

void
empz_set_ii(empz_t z, eint32_t l, eint32_t h)
{
    if (h) {
	mpz_set_si(z, h);
	mpz_mul_2exp(z, z, 32);
	mpz_add_ui(z, z, l);
    }
    else
	mpz_set_si(z, l);
}

void
empz_set_u(empz_t z, euint_t u)
{
    if (u & 0xffffffff00000000LL) {
	mpz_set_ui(z, (euint_t)u >> 32);
	mpz_mul_2exp(z, z, 32);
	mpz_add_ui(z, z, u & 0xffffffff);
    }
    else
	mpz_set_ui(z, u);
}

void
empz_set_uu(empz_t z, euint32_t l, euint32_t h)
{
    if (h) {
	mpz_set_ui(z, h);
	mpz_mul_2exp(z, z, 32);
	mpz_add_ui(z, z, l);
    }
    else
	mpz_set_ui(z, l);
}

eint32_t
empq_cmp_i(empq_t q, eint_t i)
{
    if (emp_si_p(i))
	return (mpq_cmp_si(q, i, 1));
    empq_set_i(thr_q0, i);
    return (mpq_cmp(q, thr_q0));
}

void
empq_set_i(empq_t q, eint_t i)
{
    if (!emp_si_p(i)) {
	mpz_set_si(mpq_numref(q), i >> 32);
	mpz_mul_2exp(mpq_numref(q), mpq_numref(q), 32);
	mpz_add_ui(mpq_numref(q), mpq_numref(q), i & 0xffffffff);
	mpz_set_ui(mpq_denref(q), 1);
    }
    else
	mpq_set_si(q, i, 1);
}

void
empq_set_i_i(empq_t q, eint_t n, eint_t d)
{
    empz_set_i(mpq_numref(q), n);
    empz_set_i(mpq_denref(q), d);
}

eint32_t
empr_cmp_i(empr_t r, eint_t i)
{
    if (emp_si_p(i))
	return (mpfr_cmp_si(r, i));
    empr_set_i(thr_rr0, i);
    return (mpfr_cmp(r, thr_rr0));
}

void
empr_set_i(empr_t r, eint_t i)
{
    if (!emp_si_p(i)) {
	mpfr_set_si(r, i >> 32, thr_rnd);
	mpfr_mul_2exp(r, r, 32, thr_rnd);
	mpfr_add_ui(r, r, i & 0xffffffff, thr_rnd);
    }
    else
	mpfr_set_si(r, i, thr_rnd);
}

void
empc_set_i(empc_t c, eint_t i)
{
    if (!emp_si_p(i)) {
	mpfr_set_si(mpc_realref(c), i >> 32, thr_rnd);
	mpfr_mul_2exp(mpc_realref(c), mpc_realref(c), 32, thr_rnd);
	mpfr_add_ui(mpc_realref(c), mpc_realref(c), i & 0xffffffff, thr_rnd);
	mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
    }
    else
	mpc_set_si(c, i, thr_rndc);
}

void
empc_set_i_i(empc_t c, eint_t r, eint_t i)
{
    if (!emp_si_p(r)) {
	mpfr_set_si(mpc_realref(c), r >> 32, thr_rnd);
	mpfr_mul_2exp(mpc_realref(c), mpc_realref(c), 32, thr_rnd);
	mpfr_add_ui(mpc_realref(c), mpc_realref(c), r & 0xffffffff, thr_rnd);
	if (!emp_si_p(i)) {
	    mpfr_set_si(mpc_imagref(c), i >> 32, thr_rnd);
	    mpfr_mul_2exp(mpc_imagref(c), mpc_imagref(c), 32, thr_rnd);
	    mpfr_add_ui(mpc_imagref(c), mpc_imagref(c), i & 0xffffffff, thr_rnd);
	}
	else
	    mpfr_set_si(mpc_imagref(c), i, thr_rnd);
    }
    else if (!emp_si_p(i)) {
	mpfr_set_si(mpc_realref(c), r, thr_rnd);
	mpfr_set_si(mpc_imagref(c), i >> 32, thr_rnd);
	mpfr_mul_2exp(mpc_imagref(c), mpc_imagref(c), 32, thr_rnd);
	mpfr_add_ui(mpc_imagref(c), mpc_imagref(c), i & 0xffffffff, thr_rnd);
    }
    else
	mpc_set_si_si(c, r, i, thr_rndc);
}
#else		/* __WORDSIZE == 32 */
eint_t
empz_get_i(empz_t z)
{
    mp_size_t	n;
    mp_ptr	p;
    eint_t	i;

    p = z->_mp_d;
    n = z->_mp_size;

    if (n > 0)
	i = p[0];
    else if (n < 0) {
	i = p[0];
	i = -i;
    }
    else
	i = 0;

    return (i);
}
#endif		/* __WORDSIZE == 32 */

void
empz_set_r(empz_t z, empr_t r)
{
    if (unlikely(!mpfr_number_p(r)))
	ethread_kill(SIGFPE);
    mpfr_get_z(z, r, GMP_RNDZ);
}

#if defined(__ppc__)
void
empq_div(empq_t q, empq_t a, empq_t b)
{
    if (unlikely(mpz_sgn(mpq_denref(a)) == 0 ||
		 mpz_sgn(mpq_numref(b)) == 0))
	ethread_kill(SIGFPE);
    mpq_div(q, a, b);
}

void
empq_inv(empq_t q, empq_t a)
{
    if (unlikely(mpz_sgn(mpq_numref(a)) == 0))
	ethread_kill(SIGFPE);
    mpq_inv(q, a);
}
#endif

eint_t
empq_get_i(empq_t q)
{
    eint_t	r;

    if (empz_fit_i(mpq_numref(q)) && empz_fit_i(mpq_denref(q)))
	r = empz_get_i(mpq_numref(q)) / empz_get_i(mpq_denref(q));
    else {
	mpz_set_q(thr_z0, q);
	r = empz_get_i(thr_z0);
    }

    return (r);
}

eint_t
empr_get_i(empr_t r)
{
    eint_t	i;

    if (unlikely(!mpfr_number_p(r)))
	ethread_kill(SIGFPE);
    if (mpfr_fits_slong_p(r, GMP_RNDZ))
	i = mpfr_get_si(r, GMP_RNDZ);
    else {
	mpfr_get_z(thr_z0, r, GMP_RNDZ);
	i = empz_get_i(thr_z0);
    }

    return (i);
}

eint32_t
ez_com(empz_t z, empz_t a)
{
    mpz_com(z, a);
    return (empz_fit_i(z));
}

eint32_t
ez_and_i_z(empz_t z, eint_t a, empz_t b)
{
    empz_set_i(thr_z0, a);
    mpz_and(z, thr_z0, b);
    return (empz_fit_i(z));
}

eint32_t
ez_and_z_i(empz_t z, empz_t a, eint_t b)
{
    empz_set_i(thr_z0, b);
    mpz_and(z, a, thr_z0);
    return (empz_fit_i(z));
}

eint32_t
ez_and_z_z(empz_t z, empz_t a, empz_t b)
{
    mpz_and(z, a, b);
    return (empz_fit_i(z));
}

void
ez_or_i_z(empz_t z, eint_t a, empz_t b)
{
    empz_set_i(thr_z0, a);
    mpz_ior(z, thr_z0, b);
}

void
ez_or_z_i(empz_t z, empz_t a, eint_t b)
{
    empz_set_i(thr_z0, b);
    mpz_ior(z, a, thr_z0);
}

eint32_t
ez_xor_i_z(empz_t z, eint_t a, empz_t b)
{
    empz_set_i(thr_z0, a);
    mpz_xor(z, thr_z0, b);
    return (empz_fit_i(z));
}

eint32_t
ez_xor_z_i(empz_t z, empz_t a, eint_t b)
{
    empz_set_i(thr_z0, b);
    mpz_xor(z, a, thr_z0);
    return (empz_fit_i(z));
}

eint32_t
ez_xor_z_z(empz_t z, empz_t a, empz_t b)
{
    mpz_xor(z, a, b);
    return (empz_fit_i(z));
}

eint_t
ez_mul2_i_i(empz_t z, eint_t a, eint32_t b)
{
    if (likely(b < 64)) {
	eint_t	i;

	i = a << b;
	if (likely(i >> b == a && i != MININT))
	    return (i);
    }
    empz_set_i(z, a);
    ez_shl_z_i(z, z, b);
    return (MININT);
}

eint32_t
eq_mul2_q_i(empq_t q, empq_t a, eint32_t b)
{
    mpq_mul_2exp(q, a, b);
    if (mpz_cmp_ui(mpq_denref(q), 1))
	return (0);
    return (empz_fit_i(mpq_numref(q)) ? -1 : 1);
}

ecdd_t
edd_mul2_dd_i(ecdd_t a, eint32_t b)
{
    ecdd_t	dd;

    real(dd) = ldexp(real(a), b);
    imag(dd) = ldexp(imag(a), b);

    return (dd);
}

eint_t
eq_div2_i_i(empq_t q, eint_t a, eint32_t b)
{
    eint_t	i;

    if (b < 64) {
	i = a >> b;
	if (likely(i << b == a))
	    return (i);
    }
    empq_set_i(q, a);
    mpq_div_2exp(q, q, b);
    return (MININT);
}

eint32_t
eq_div2_z_i(empq_t q, empz_t a, eint32_t b)
{
    mpq_set_z(q, a);
    mpq_div_2exp(q, q, b);
    if (mpz_cmp_ui(mpq_denref(q), 1))
	return (0);
    return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
}

eint32_t
eq_div2_q_i(empq_t q, empq_t a, eint32_t b)
{
    mpq_div_2exp(q, a, b);
    if (mpz_cmp_ui(mpq_denref(q), 1))
	return (0);
    return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
}

ecdd_t
edd_div2_dd_i(ecdd_t a, eint32_t b)
{
    ecdd_t	dd;

    real(dd) = ldexp(real(a), -b);
    imag(dd) = ldexp(imag(a), -b);

    return (dd);
}

eint32_t
ez_shl_d_i(empz_t z, efloat_t a, eint32_t b)
{
    mpz_set_d(z, floor(a));
    ez_shl_z_i(z, z, b);
    return (empz_fit_i(z));
}

eint32_t
ez_shl_q_i(empz_t z, empq_t a, eint32_t b)
{
    mpz_fdiv_q(z, mpq_numref(a), mpq_denref(a));
    ez_shl_z_i(z, z, b);
    return (empz_fit_i(z));
}

eint32_t
ez_shl_r_i(empz_t z, empr_t a, eint32_t b)
{
    mpfr_floor(thr_rr0, a);
    empz_set_r(z, thr_rr0);
    ez_shl_z_i(z, z, b);
    return (empz_fit_i(z));
}

eint_t
ez_shr_d_i(empz_t z, efloat_t a, eint32_t b)
{
    efloat_t	d;
    d = floor(ldexp(a, -b));
    if ((eint_t)d == d && d != MININT)
	return (d);
    mpz_set_d(z, a);
    mpz_fdiv_q_2exp(z, z, b);
    if (empz_fit_i(z))
	return (empz_get_i(z));
    return (MININT);
}

eint32_t
ez_shr_z_i(empz_t z, empz_t a, eint32_t b)
{
    mpz_fdiv_q_2exp(z, a, b);
    return (empz_fit_i(z));
}

eint32_t
ez_shr_q_i(empz_t z, empq_t a, eint32_t b)
{
    mpz_fdiv_q(z, mpq_numref(a), mpq_denref(a));
    mpz_fdiv_q_2exp(z, z, b);
    return (empz_fit_i(z));
}

eint32_t
ez_shr_r_i(empz_t z, empr_t a, eint32_t b)
{
    mpfr_div_2exp(thr_rr0, a, b, thr_rnd);
    mpfr_floor(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z));
}

void
ez_add_i_i(empz_t z, eint_t a, eint_t b)
{
    empz_set_i(z, a);
    if (emp_ui_p(b))
	mpz_add_ui(z, z, b);
    else {
	empz_set_i(thr_z0, b);
	mpz_add(z, z, thr_z0);
    }
}

eint32_t
ez_add_i_z(empz_t z, eint_t a, empz_t b)
{
    if (emp_ui_p(a))
	mpz_add_ui(z, b, a);
    else if (z == b) {
	empz_set_i(thr_z0, a);
	mpz_add(z, thr_z0, b);
    }
    else {
	empz_set_i(z, a);
	mpz_add(z, z, b);
    }
    return (empz_fit_i(z));
}

eint_t
ez_add_z_i(empz_t z, empz_t a, eint_t b)
{
    if (emp_ui_p(b))
	mpz_add_ui(z, a, b);
    else if (z == a) {
	empz_set_i(thr_z0, b);
	mpz_add(z, a, thr_z0);
    }
    else {
	empz_set_i(z, b);
	mpz_add(z, a, z);
    }
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_add_z_z(empz_t z, empz_t a, empz_t b)
{
    mpz_add(z, a, b);
    return (empz_fit_i(z));
}

eint32_t
eq_add_i_q(empq_t q, eint_t a, empq_t b)
{
    if (q == b) {
	if (emp_ui_p(a))
	    mpz_addmul_ui(mpq_numref(q), mpq_denref(q), a);
	else {
	    empq_set_i(thr_q0, a);
	    mpq_add(q, thr_q0, q);
	}
    }
    else {
	empq_set_i(thr_q0, a);
	mpq_add(q, thr_q0, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_add_z_q(empq_t q, empz_t a, empq_t b)
{
    if (q == b)
	mpz_addmul(mpq_numref(q), mpq_denref(q), a);
    else {
	mpq_set_z(thr_q0, a);
	mpq_add(q, thr_q0, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_add_q_i(empq_t q, empq_t a, eint_t b)
{
    if (q == a) {
	empq_set_i(thr_q0, b);
	mpq_add(q, a, thr_q0);
    }
    else {
	empq_set_i(q, b);
	mpq_add(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_add_q_z(empq_t q, empq_t a, empz_t b)
{
    if (q == a) {
	mpq_set_z(thr_q0, b);
	mpq_add(q, a, thr_q0);
    }
    else {
	mpq_set_z(q, b);
	mpq_add(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_add_q_q(empq_t q, empq_t a, empq_t b)
{
    mpq_add(q, a, b);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

void
er_add_i_r(empr_t r, eint_t a, empr_t b)
{
    if (r == b) {
	empr_set_i(thr_rr0, a);
	er_add_r_r(r, thr_rr0, b);
    }
    else {
	empr_set_i(r, a);
	er_add_r_r(r, r, b);
    }
}

void
er_add_d_r(empr_t r, efloat_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_d(thr_rr0, a, thr_rnd);
	er_add_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_d(r, a, thr_rnd);
	er_add_r_r(r, r, b);
    }
}

void
er_add_z_r(empr_t r, empz_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_z(thr_rr0, a, thr_rnd);
	er_add_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_z(r, a, thr_rnd);
	er_add_r_r(r, r, b);
    }
}

void
er_add_q_r(empr_t r, empq_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_q(thr_rr0, a, thr_rnd);
	er_add_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_q(r, a, thr_rnd);
	er_add_r_r(r, r, b);
    }
}

void
er_add_r_i(empr_t r, empr_t a, eint_t b)
{
    if (r == a) {
	empr_set_i(thr_rr0, b);
	er_add_r_r(r, a, thr_rr0);
    }
    else {
	empr_set_i(r, b);
	er_add_r_r(r, a, r);
    }
}

void
er_add_r_z(empr_t r, empr_t a, empz_t b)
{
    if (r == a) {
	mpfr_set_z(thr_rr0, b, thr_rnd);
	er_add_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_z(r, b, thr_rnd);
	er_add_r_r(r, a, r);
    }
}

void
er_add_r_q(empr_t r, empr_t a, empq_t b)
{
    if (r == a) {
	mpfr_set_q(thr_rr0, b, thr_rnd);
	er_add_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_q(r, b, thr_rnd);
	er_add_r_r(r, a, r);
    }
}

ecdd_t
edd_add_d_qq(efloat_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a + d);
}

ecdd_t
edd_add_dd_qq(ecdd_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a + d);
}

ecdd_t
edd_add_qq_dd(ecqq_t a, ecdd_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d + b);
}

void
eqq_add_qq_i(ecqq_t q, ecqq_t a, eint_t b)
{
    eq_add_q_i(cqq_realref(q), cqq_realref(a), b);
    if (q != a)
	mpq_set(cqq_imagref(q), cqq_imagref(a));
}

ecdd_t
edd_add_qq_d(ecqq_t a, efloat_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d + b);
}

void
eqq_add_i_qq(ecqq_t q, eint_t a, ecqq_t b)
{
    eq_add_i_q(cqq_realref(q), a, cqq_realref(b));
    if (q != b)
	mpq_set(cqq_imagref(q), cqq_imagref(b));
}

void
eqq_add_z_qq(ecqq_t q, empz_t a, ecqq_t b)
{
    eq_add_z_q(cqq_realref(q), a, cqq_realref(b));
    if (q != b)
	mpq_set(cqq_imagref(q), cqq_imagref(b));
}

void
eqq_add_q_qq(ecqq_t q, empq_t a, ecqq_t b)
{
    mpq_add(cqq_realref(q), a, cqq_realref(b));
    if (q != b)
	mpq_set(cqq_imagref(q), cqq_imagref(b));
}

void
eqq_add_qq_z(ecqq_t q, ecqq_t a, empz_t b)
{
    eq_add_q_z(cqq_realref(q), cqq_realref(a), b);
    if (q != a)
	mpq_set(cqq_imagref(q), cqq_imagref(a));
}

void
eqq_add_qq_q(ecqq_t q, ecqq_t a, empq_t b)
{
    mpq_add(cqq_realref(q), cqq_realref(a), b);
    if (q != a)
	mpq_set(cqq_imagref(q), cqq_imagref(a));
}

void
ecc_add_i_cc(empc_t c, eint_t a, empc_t b)
{
    if (c == b) {
	empc_set_i(thr_c0, a);
	ecc_add_cc_cc(c, thr_c0, b);
    }
    else {
	empc_set_i(c, a);
	ecc_add_cc_cc(c, c, b);
    }
}

void
ecc_add_d_cc(empc_t c, efloat_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d(thr_c0, a, thr_rndc);
	ecc_add_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d(c, a, thr_rndc);
	ecc_add_cc_cc(c, c, b);
    }
}

void
ecc_add_z_cc(empc_t c, empz_t a, empc_t b)
{
    if (c == b) {
	mpc_set_z(thr_c0, a, thr_rndc);
	ecc_add_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_z(c, a, thr_rndc);
	ecc_add_cc_cc(c, c, b);
    }
}

void
ecc_add_q_cc(empc_t c, empq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q(thr_c0, a, thr_rndc);
	ecc_add_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q(c, a, thr_rndc);
	ecc_add_cc_cc(c, c, b);
    }
}

void
ecc_add_r_dd(empc_t c, empr_t a, ecdd_t b)
{
    mpc_set_d_d(c, real(b), imag(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_add_cc_cc(c, thr_c0, c);
}

void
ecc_add_r_qq(empc_t c, empr_t a, ecqq_t b)
{
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_add_cc_cc(c, thr_c0, c);
}

void
ecc_add_r_cc(empc_t c, empr_t a, empc_t b)
{
    if (c == b) {
	mpc_set_fr(thr_c0, a, thr_rndc);
	ecc_add_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_fr(c, a, thr_rndc);
	ecc_add_cc_cc(c, c, b);
    }
}

void
ecc_add_dd_r(empc_t c, ecdd_t a, empr_t b)
{
    mpc_set_d_d(c, real(a), imag(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_add_cc_cc(c, c, thr_c0);
}

void
ecc_add_dd_cc(empc_t c, ecdd_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
	ecc_add_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d_d(c, real(a), imag(a), thr_rndc);
	ecc_add_cc_cc(c, c, b);
    }
}

void
ecc_add_qq_r(empc_t c, ecqq_t a, empr_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_add_cc_cc(c, c, thr_c0);
}

void
ecc_add_qq_cc(empc_t c, ecqq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_add_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_add_cc_cc(c, c, b);
    }
}

void
ecc_add_cc_i(empc_t c, empc_t a, eint_t b)
{
    if (c == a) {
	empc_set_i(thr_c0, b);
	ecc_add_cc_cc(c, a, thr_c0);
    }
    else {
	empc_set_i(c, b);
	ecc_add_cc_cc(c, a, c);
    }
}

void
ecc_add_cc_d(empc_t c, empc_t a, efloat_t b)
{
    if (c == a) {
	mpc_set_d(thr_c0, b, thr_rndc);
	ecc_add_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d(c, b, thr_rndc);
	ecc_add_cc_cc(c, a, c);
    }
}

void
ecc_add_cc_z(empc_t c, empc_t a, empz_t b)
{
    if (c == a) {
	mpc_set_z(thr_c0, b, thr_rndc);
	ecc_add_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_z(c, b, thr_rndc);
	ecc_add_cc_cc(c, a, c);
    }
}

void
ecc_add_cc_q(empc_t c, empc_t a, empq_t b)
{
    if (c == a) {
	mpc_set_q(thr_c0, b, thr_rndc);
	ecc_add_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q(c, b, thr_rndc);
	ecc_add_cc_cc(c, a, c);
    }
}

void
ecc_add_cc_r(empc_t c, empc_t a, empr_t b)
{
    if (c == a) {
	mpc_set_fr(thr_c0, b, thr_rndc);
	ecc_add_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_fr(c, b, thr_rndc);
	ecc_add_cc_cc(c, a, c);
    }
}

void
ecc_add_cc_dd(empc_t c, empc_t a, ecdd_t b)
{
    if (c == a) {
	mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
	ecc_add_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d_d(c, real(b), imag(b), thr_rndc);
	ecc_add_cc_cc(c, a, c);
    }
}

void
ecc_add_cc_qq(empc_t c, empc_t a, ecqq_t b)
{
    if (c == a) {
	mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_add_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_add_cc_cc(c, a, c);
    }
}

void
ez_sub_i_i(empz_t z, eint_t a, eint_t b)
{
    empz_set_i(z, a);
    if (emp_ui_p(b))
	mpz_sub_ui(z, z, b);
    else {
	empz_set_i(thr_z0, b);
	mpz_sub(z, z, thr_z0);
    }
}

eint32_t
ez_sub_i_z(empz_t z, eint_t a, empz_t b)
{
    if (emp_ui_p(a))
	mpz_ui_sub(z, a, b);
    else if (z == b) {
	empz_set_i(thr_z0, a);
	mpz_sub(z, thr_z0, b);
    }
    else {
	empz_set_i(z, a);
	mpz_sub(z, z, b);
    }
    return (empz_fit_i(z));
}

eint32_t
eq_sub_i_q(empq_t q, eint_t a, empq_t b)
{
    if (q == b) {
	empq_set_i(thr_q0, a);
	mpq_sub(q, thr_q0, b);
    }
    else {
	empq_set_i(q, a);
	mpq_sub(q, q, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint_t
ez_sub_z_i(empz_t z, empz_t a, eint_t b)
{
    if (emp_ui_p(b))
	mpz_sub_ui(z, a, b);
    else if (z == a) {
	empz_set_i(thr_z0, b);
	mpz_sub(z, a, thr_z0);
    }
    else {
	empz_set_i(z, b);
	mpz_sub(z, a, z);
    }
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_sub_z_z(empz_t z, empz_t a, empz_t b)
{
    mpz_sub(z, a, b);
    return (empz_fit_i(z));
}

eint32_t
eq_sub_z_q(empq_t q, empz_t a, empq_t b)
{
    if (q == b) {
	mpq_set_z(thr_q0, a);
	mpq_sub(q, thr_q0, b);
    }
    else {
	mpq_set_z(q, a);
	mpq_sub(q, q, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_sub_q_i(empq_t q, empq_t a, eint_t b)
{
    if (q == a) {
	empq_set_i(thr_q0, b);
	mpq_sub(q, a, thr_q0);
    }
    else {
	empq_set_i(q, b);
	mpq_sub(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_sub_q_z(empq_t q, empq_t a, empz_t b)
{
    if (q == a) {
	mpq_set_z(thr_q0, b);
	mpq_sub(q, a, thr_q0);
    }
    else {
	mpq_set_z(q, b);
	mpq_sub(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_sub_q_q(empq_t q, empq_t a, empq_t b)
{
    mpq_sub(q, a, b);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

void
er_sub_i_r(empr_t r, eint_t a, empr_t b)
{
    if (r == b) {
	empr_set_i(thr_rr0, a);
	er_sub_r_r(r, thr_rr0, b);
    }
    else {
	empr_set_i(r, a);
	er_sub_r_r(r, r, b);
    }
}

void
er_sub_z_r(empr_t r, empz_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_z(thr_rr0, a, thr_rnd);
	er_sub_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_z(r, a, thr_rnd);
	er_sub_r_r(r, r, b);
    }
}

void
er_sub_q_r(empr_t r, empq_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_q(thr_rr0, a, thr_rnd);
	er_sub_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_q(r, a, thr_rnd);
	er_sub_r_r(r, r, b);
    }
}

void
er_sub_r_i(empr_t r, empr_t a, eint_t b)
{
    if (r == a) {
	empr_set_i(thr_rr0, b);
	er_sub_r_r(r, a, thr_rr0);
    }
    else {
	empr_set_i(r, b);
	er_sub_r_r(r, a, r);
    }
}

void
er_sub_r_z(empr_t r, empr_t a, empz_t b)
{
    if (r == a) {
	mpfr_set_z(thr_rr0, b, thr_rnd);
	er_sub_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_z(r, b, thr_rnd);
	er_sub_r_r(r, a, r);
    }
}

void
er_sub_r_q(empr_t r, empr_t a, empq_t b)
{
    if (r == a) {
	mpfr_set_q(thr_rr0, b, thr_rnd);
	er_sub_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_q(r, b, thr_rnd);
	er_sub_r_r(r, a, r);
    }
}

ecdd_t
edd_sub_d_qq(efloat_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a - d);
}

ecdd_t
edd_sub_dd_qq(ecdd_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a - d);
}

ecdd_t
edd_sub_qq_d(ecqq_t a, efloat_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d - b);
}

ecdd_t
edd_sub_qq_dd(ecqq_t a, ecdd_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d - b);
}

void
eqq_sub_i_qq(ecqq_t q, eint_t a, ecqq_t b)
{
    eq_sub_i_q(cqq_realref(q), a, cqq_realref(b));
    mpq_neg(cqq_imagref(q), cqq_imagref(b));
}

void
eqq_sub_z_qq(ecqq_t q, empz_t a, ecqq_t b)
{
    eq_sub_z_q(cqq_realref(q), a, cqq_realref(b));
    mpq_neg(cqq_imagref(q), cqq_imagref(b));
}

void
eqq_sub_q_qq(ecqq_t q, empq_t a, ecqq_t b)
{
    mpq_sub(cqq_realref(q), a, cqq_realref(b));
    mpq_neg(cqq_imagref(q), cqq_imagref(b));
}

void
eqq_sub_qq_i(ecqq_t q, ecqq_t a, eint_t b)
{
    eq_sub_q_i(cqq_realref(q), cqq_realref(a), b);
    if (q != a)
	mpq_set(cqq_imagref(q), cqq_imagref(a));
}

void
eqq_sub_qq_z(ecqq_t q, ecqq_t a, empz_t b)
{
    eq_sub_q_z(cqq_realref(q), cqq_realref(a), b);
    if (q != a)
	mpq_set(cqq_imagref(q), cqq_imagref(a));
}

void
eqq_sub_qq_q(ecqq_t q, ecqq_t a, empq_t b)
{
    mpq_sub(cqq_realref(q), cqq_realref(a), b);
    if (q != a)
	mpq_set(cqq_imagref(q), cqq_imagref(a));
}

void
ecc_sub_i_cc(empc_t c, eint_t a, empc_t b)
{
    if (c == b) {
	empc_set_i(thr_c0, a);
	ecc_sub_cc_cc(c, thr_c0, b);
    }
    else {
	empc_set_i(c, a);
	ecc_sub_cc_cc(c, c, b);
    }
}

void
ecc_sub_d_cc(empc_t c, efloat_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d(thr_c0, a, thr_rndc);
	ecc_sub_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d(c, a, thr_rndc);
	ecc_sub_cc_cc(c, c, b);
    }
}

void
ecc_sub_z_cc(empc_t c, empz_t a, empc_t b)
{
    if (c == b) {
	mpc_set_z(thr_c0, a, thr_rndc);
	ecc_sub_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_z(c, a, thr_rndc);
	ecc_sub_cc_cc(c, c, b);
    }
}

void
ecc_sub_q_cc(empc_t c, empq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q(thr_c0, a, thr_rndc);
	ecc_sub_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q(c, a, thr_rndc);
	ecc_sub_cc_cc(c, c, b);
    }
}

void
ecc_sub_r_dd(empc_t c, empr_t a, ecdd_t b)
{
    mpc_set_d_d(c, real(b), imag(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_sub_cc_cc(c, thr_c0, c);
}

void
ecc_sub_r_qq(empc_t c, empr_t a, ecqq_t b)
{
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_sub_cc_cc(c, thr_c0, c);
}

void
ecc_sub_r_cc(empc_t c, empr_t a, empc_t b)
{
    if (c == b) {
	mpc_set_fr(thr_c0, a, thr_rndc);
	ecc_sub_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_fr(c, a, thr_rndc);
	ecc_sub_cc_cc(c, c, b);
    }
}

void
ecc_sub_dd_r(empc_t c, ecdd_t a, empr_t b)
{
    mpc_set_d_d(c, real(a), imag(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_sub_cc_cc(c, c, thr_c0);
}

void
ecc_sub_dd_cc(empc_t c, ecdd_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
	ecc_sub_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d_d(c, real(a), imag(a), thr_rndc);
	ecc_sub_cc_cc(c, c, b);
    }
}

void
ecc_sub_qq_r(empc_t c, ecqq_t a, empr_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_sub_cc_cc(c, c, thr_c0);
}

void
ecc_sub_qq_cc(empc_t c, ecqq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_sub_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_sub_cc_cc(c, c, b);
    }
}

void
ecc_sub_cc_i(empc_t c, empc_t a, eint_t b)
{
    if (c == a) {
	empc_set_i(thr_c0, b);
	ecc_sub_cc_cc(c, a, thr_c0);
    }
    else {
	empc_set_i(c, b);
	ecc_sub_cc_cc(c, a, c);
    }
}

void
ecc_sub_cc_d(empc_t c, empc_t a, efloat_t b)
{
    if (c == a) {
	mpc_set_d(thr_c0, b, thr_rndc);
	ecc_sub_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d(c, b, thr_rndc);
	ecc_sub_cc_cc(c, a, c);
    }
}

void
ecc_sub_cc_z(empc_t c, empc_t a, empz_t b)
{
    if (c == a) {
	mpc_set_z(thr_c0, b, thr_rndc);
	ecc_sub_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_z(c, b, thr_rndc);
	ecc_sub_cc_cc(c, a, c);
    }
}

void
ecc_sub_cc_q(empc_t c, empc_t a, empq_t b)
{
    if (c == a) {
	mpc_set_q(thr_c0, b, thr_rndc);
	ecc_sub_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q(c, b, thr_rndc);
	ecc_sub_cc_cc(c, a, c);
    }
}

void
ecc_sub_cc_r(empc_t c, empc_t a, empr_t b)
{
    if (c == a) {
	mpc_set_fr(thr_c0, b, thr_rndc);
	ecc_sub_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_fr(c, b, thr_rndc);
	ecc_sub_cc_cc(c, a, c);
    }
}

void
ecc_sub_cc_dd(empc_t c, empc_t a, ecdd_t b)
{
    if (c == a) {
	mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
	ecc_sub_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d_d(c, real(b), imag(b), thr_rndc);
	ecc_sub_cc_cc(c, a, c);
    }
}

void
ecc_sub_cc_qq(empc_t c, empc_t a, ecqq_t b)
{
    if (c == a) {
	mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_sub_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_sub_cc_cc(c, a, c);
    }
}

eint_t
ei_mul_i_i(eint_t a, eint_t b)
{
    /* shameless cut&paste + adaptation/indent-style-change
     * from libgcc multiplication overflow check */
    const edata_t uu = { .L = a };
    const edata_t vv = { .L = b };

    if (likely(uu.s.h == uu.s.l >> 31)) {
	/* a fits in a single eint32_t */
	if (likely(vv.s.h == vv.s.l >> 31)) {
	    /* b fits in a single eint32_t as well */
	    /* a single multiplication, no overflow risk */
	    return ((eint64_t)uu.s.l * (eint64_t)vv.s.l);
	}
	else {
	    /* two multiplications */
	    edata_t w0 = {
		.L = (euint64_t)(euint32_t)uu.s.l *
		     (euint64_t)(euint32_t)vv.s.l
	    };
	    edata_t w1 = {
		.L = (euint64_t)(euint32_t)uu.s.l *
		     (euint64_t)(euint32_t)vv.s.h
	    };

	    if (vv.s.h < 0)
		w1.s.h -= uu.s.l;
	    if (uu.s.l < 0)
		w1.L -= vv.L;
	    w1.L += (euint32_t)w0.s.h;
	    if (likely(w1.s.h == w1.s.l >> 31)) {
		w0.s.h = w1.s.l;
		return (w0.L);
	    }
	}
    }
    else if (likely(vv.s.h == vv.s.l >> 31)) {
	/* b fits into a single eint32_t */
	/* two multiplications */
	edata_t w0 = {
	    .L = (euint64_t)(euint32_t)uu.s.l *
		 (euint64_t)(euint32_t)vv.s.l
	};
	edata_t w1 = {
	    .L = (euint64_t)(euint32_t)uu.s.h *
		 (euint64_t)(euint32_t)vv.s.l };

	if (uu.s.h < 0)
	    w1.s.h -= vv.s.l;
	if (vv.s.l < 0)
	    w1.L -= uu.L;
	w1.L += (euint32_t)w0.s.h;
	if (likely(w1.s.h == w1.s.l >> 31)) {
	    w0.s.h = w1.s.l;
	    return (w0.L);
	}
    }
    /* A few sign checks and a single multiplication */
    else if (uu.s.h >= 0) {
	if (vv.s.h >= 0) {
	    if (uu.s.h == 0 && vv.s.h == 0) {
		const eint_t w = (euint64_t)(euint32_t)uu.s.l *
				 (euint64_t)(euint32_t)vv.s.l;

		if (likely(w >= 0))
		    return (w);
	    }
	}
	else if (uu.s.h == 0 && vv.s.h == (eint32_t)-1) {
	    edata_t w0 = {
		.L = (euint64_t)(euint32_t)uu.s.l *
		     (euint64_t)(euint32_t)vv.s.l };

	    w0.s.h -= uu.s.l;
	    if (likely(w0.s.h < 0))
		return (w0.L);
	}
    }
    else if (vv.s.h >= 0) {
	if (uu.s.h == (eint32_t) -1 && vv.s.h == 0) {
	    edata_t w0 = {
		.L = (euint64_t)(euint32_t) uu.s.l *
		     (euint64_t)(euint32_t) vv.s.l };

	    w0.s.h -= vv.s.l;
	    if (likely(w0.s.h < 0))
		return (w0.L);
	}
    }
    else if (uu.s.h == (eint32_t)-1 && vv.s.h == (eint32_t)-1) {
	edata_t w0 = {
	    .L = (euint64_t)(euint32_t)uu.s.l *
		 (euint64_t)(euint32_t) vv.s.l };

	w0.s.h -= uu.s.l;
	w0.s.h -= vv.s.l;
	if (likely(w0.s.h >= 0))
	    return (w0.L);
    }

    return (MININT);
}

void
ez_mul_i_i(empz_t z, eint_t a, eint_t b)
{
    empz_set_i(z, a);
    if (emp_si_p(b))
	mpz_mul_si(z, z, b);
    else {
	empz_set_i(thr_z0, b);
	mpz_mul(z, z, thr_z0);
    }
}

eint32_t
ez_mul_i_z(empz_t z, eint_t a, empz_t b)
{
    if (emp_si_p(a))
	mpz_mul_si(z, b, a);
    else if (z == b) {
	empz_set_i(thr_z0, a);
	mpz_mul(z, thr_z0, b);
    }
    else {
	empz_set_i(z, a);
	mpz_mul(z, z, b);
    }
    return (empz_fit_i(z));
}

eint_t
ez_mul_z_i(empz_t z, empz_t a, eint_t b)
{
    if (emp_si_p(b))
	mpz_mul_si(z, a, b);
    else if (z == a) {
	empz_set_i(thr_z0, b);
	mpz_mul(z, a, thr_z0);
    }
    else {
	empz_set_i(z, b);
	mpz_mul(z, a, z);
    }
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_mul_z_z(empz_t z, empz_t a, empz_t b)
{
    mpz_mul(z, a, b);
    return (empz_fit_i(z));
}

eint32_t
eq_mul_i_q(empq_t q, eint_t a, empq_t b)
{
    if (q == b) {
	empq_set_i(thr_q0, a);
	mpq_mul(q, thr_q0, b);
    }
    else {
	empq_set_i(q, a);
	mpq_mul(q, q, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_mul_z_q(empq_t q, empz_t a, empq_t b)
{
    if (q == b) {
	mpq_set_z(thr_q0, a);
	mpq_mul(q, thr_q0, b);
    }
    else {
	mpq_set_z(q, a);
	mpq_mul(q, q, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_mul_q_i(empq_t q, empq_t a, eint_t b)
{
    if (q == a) {
	empq_set_i(thr_q0, b);
	mpq_mul(q, a, thr_q0);
    }
    else {
	empq_set_i(q, b);
	mpq_mul(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_mul_q_z(empq_t q, empq_t a, empz_t b)
{
    if (q == a) {
	mpq_set_z(thr_q0, b);
	mpq_mul(q, a, thr_q0);
    }
    else {
	mpq_set_z(q, b);
	mpq_mul(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_mul_q_q(empq_t q, empq_t a, empq_t b)
{
    mpq_mul(q, a, b);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

void
er_mul_i_r(empr_t r, eint_t a, empr_t b)
{
    if (r == b) {
	empr_set_i(thr_rr0, a);
	er_mul_r_r(r, thr_rr0, b);
    }
    else {
	empr_set_i(r, a);
	er_mul_r_r(r, r, b);
    }
}

void
er_mul_d_r(empr_t r, efloat_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_d(thr_rr0, a, thr_rnd);
	er_mul_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_d(r, a, thr_rnd);
	er_mul_r_r(r, r, b);
    }
}

void
er_mul_z_r(empr_t r, empz_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_z(thr_rr0, a, thr_rnd);
	er_mul_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_z(r, a, thr_rnd);
	er_mul_r_r(r, r, b);
    }
}

void
er_mul_q_r(empr_t r, empq_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_q(thr_rr0, a, thr_rnd);
	er_mul_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_q(r, a, thr_rnd);
	er_mul_r_r(r, r, b);
    }
}

void
er_mul_r_i(empr_t r, empr_t a, eint_t b)
{
    if (r == a) {
	empr_set_i(thr_rr0, b);
	er_mul_r_r(r, a, thr_rr0);
    }
    else {
	empr_set_i(r, b);
	er_mul_r_r(r, a, r);
    }
}

void
er_mul_r_z(empr_t r, empr_t a, empz_t b)
{
    if (r == a) {
	mpfr_set_z(thr_rr0, b, thr_rnd);
	er_mul_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_z(r, b, thr_rnd);
	er_mul_r_r(r, a, r);
    }
}

void
er_mul_r_q(empr_t r, empr_t a, empq_t b)
{
    if (r == a) {
	mpfr_set_q(thr_rr0, b, thr_rnd);
	er_mul_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_q(r, b, thr_rnd);
	er_mul_r_r(r, a, r);
    }
}

ecdd_t
edd_mul_d_qq(efloat_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a * d);
}

ecdd_t
edd_mul_dd_qq(ecdd_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a * d);
}

ecdd_t
edd_mul_qq_d(ecqq_t a, efloat_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d * b);
}

ecdd_t
edd_mul_qq_dd(ecqq_t a, ecdd_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d * b);
}

void
eqq_mul_i_qq(ecqq_t q, eint_t a, ecqq_t b)
{
    eq_mul_i_q(cqq_realref(q), a, cqq_realref(b));
    eq_mul_i_q(cqq_imagref(q), a, cqq_imagref(b));
}

void
eqq_mul_z_qq(ecqq_t q, empz_t a, ecqq_t b)
{
    eq_mul_z_q(cqq_realref(q), a, cqq_realref(b));
    eq_mul_z_q(cqq_imagref(q), a, cqq_imagref(b));
}

void
eqq_mul_q_qq(ecqq_t q, empq_t a, ecqq_t b)
{
    mpq_mul(cqq_realref(q), a, cqq_realref(b));
    mpq_mul(cqq_imagref(q), a, cqq_imagref(b));
}

void
eqq_mul_qq_i(ecqq_t q, ecqq_t a, eint_t b)
{
    eq_mul_q_i(cqq_realref(q), cqq_realref(a), b);
    eq_mul_q_i(cqq_imagref(q), cqq_imagref(a), b);
}

void
eqq_mul_qq_z(ecqq_t q, ecqq_t a, empz_t b)
{
    eq_mul_q_z(cqq_realref(q), cqq_realref(a), b);
    eq_mul_q_z(cqq_imagref(q), cqq_imagref(a), b);
}

void
eqq_mul_qq_q(ecqq_t q, ecqq_t a, empq_t b)
{
    mpq_mul(cqq_realref(q), cqq_realref(a), b);
    mpq_mul(cqq_imagref(q), cqq_imagref(a), b);
}

void
eqq_mul_qq_qq(ecqq_t q, ecqq_t a, ecqq_t b)
{
    mpq_mul(thr_q2, cqq_realref(a), cqq_imagref(b));
    mpq_mul(thr_q1, cqq_imagref(a), cqq_realref(b));
    mpq_add(thr_q2, thr_q2, thr_q1);
    mpq_mul(thr_q1, cqq_realref(a), cqq_realref(b));
    mpq_mul(cqq_realref(q), cqq_imagref(a), cqq_imagref(b));
    mpq_swap(cqq_imagref(q), thr_q2);
    mpq_sub(cqq_realref(q), thr_q1, cqq_realref(q));
}

void
ecc_mul_i_cc(empc_t c, eint_t a, empc_t b)
{
    if (c == b) {
	empc_set_i(thr_c0, a);
	ecc_mul_cc_cc(c, thr_c0, b);
    }
    else {
	empc_set_i(c, a);
	ecc_mul_cc_cc(c, c, b);
    }
}

void
ecc_mul_d_cc(empc_t c, efloat_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d(thr_c0, a, thr_rndc);
	ecc_mul_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d(c, a, thr_rndc);
	ecc_mul_cc_cc(c, c, b);
    }
}

void
ecc_mul_z_cc(empc_t c, empz_t a, empc_t b)
{
    if (c == b) {
	mpc_set_z(thr_c0, a, thr_rndc);
	ecc_mul_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_z(c, a, thr_rndc);
	ecc_mul_cc_cc(c, c, b);
    }
}

void
ecc_mul_q_cc(empc_t c, empq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q(thr_c0, a, thr_rndc);
	ecc_mul_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q(c, a, thr_rndc);
	ecc_mul_cc_cc(c, c, b);
    }
}

void
ecc_mul_r_dd(empc_t c, empr_t a, ecdd_t b)
{
    mpc_set_d_d(c, real(b), imag(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_mul_cc_cc(c, thr_c0, c);
}

void
ecc_mul_r_qq(empc_t c, empr_t a, ecqq_t b)
{
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_mul_cc_cc(c, thr_c0, c);
}

void
ecc_mul_r_cc(empc_t c, empr_t a, empc_t b)
{
    if (c == b) {
	mpc_set_fr(thr_c0, a, thr_rndc);
	ecc_mul_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_fr(c, a, thr_rndc);
	ecc_mul_cc_cc(c, c, b);
    }
}

void
ecc_mul_dd_r(empc_t c, ecdd_t a, empr_t b)
{
    mpc_set_d_d(c, real(a), imag(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_mul_cc_cc(c, c, thr_c0);
}

void
ecc_mul_dd_cc(empc_t c, ecdd_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
	ecc_mul_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d_d(c, real(a), imag(a), thr_rndc);
	ecc_mul_cc_cc(c, c, b);
    }
}

void
ecc_mul_qq_r(empc_t c, ecqq_t a, empr_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_mul_cc_cc(c, c, thr_c0);
}

void
ecc_mul_qq_cc(empc_t c, ecqq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_mul_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_mul_cc_cc(c, c, b);
    }
}

void
ecc_mul_cc_i(empc_t c, empc_t a, eint_t b)
{
    if (c == a) {
	empc_set_i(thr_c0, b);
	ecc_mul_cc_cc(c, a, thr_c0);
    }
    else {
	empc_set_i(c, b);
	ecc_mul_cc_cc(c, a, c);
    }
}

void
ecc_mul_cc_d(empc_t c, empc_t a, efloat_t b)
{
    if (c == a) {
	mpc_set_d(thr_c0, b, thr_rndc);
	ecc_mul_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d(c, b, thr_rndc);
	ecc_mul_cc_cc(c, a, c);
    }
}

void
ecc_mul_cc_z(empc_t c, empc_t a, empz_t b)
{
    if (c == a) {
	mpc_set_z(thr_c0, b, thr_rndc);
	ecc_mul_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_z(c, b, thr_rndc);
	ecc_mul_cc_cc(c, a, c);
    }
}

void
ecc_mul_cc_q(empc_t c, empc_t a, empq_t b)
{
    if (c == a) {
	mpc_set_q(thr_c0, b, thr_rndc);
	ecc_mul_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q(c, b, thr_rndc);
	ecc_mul_cc_cc(c, a, c);
    }
}

void
ecc_mul_cc_r(empc_t c, empc_t a, empr_t b)
{
    if (c == a) {
	mpc_set_fr(thr_c0, b, thr_rndc);
	ecc_mul_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_fr(c, b, thr_rndc);
	ecc_mul_cc_cc(c, a, c);
    }
}

void
ecc_mul_cc_dd(empc_t c, empc_t a, ecdd_t b)
{
    if (c == a) {
	mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
	ecc_mul_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d_d(c, real(b), imag(b), thr_rndc);
	ecc_mul_cc_cc(c, a, c);
    }
}

void
ecc_mul_cc_qq(empc_t c, empc_t a, ecqq_t b)
{
    if (c == a) {
	mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_mul_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_mul_cc_cc(c, a, c);
    }
}

void
eq_div_i_i(empq_t q, eint_t a, eint_t b)
{
    check_int_divide_by_zero(b);
    if (emp_ui_p(a) && emp_ui_p(b))
	mpq_set_ui(q, a, b);
    else {
	empz_set_i(mpq_numref(q), a);
	empz_set_i(mpq_denref(q), b);
    }
    mpq_canonicalize(q);
}

eint32_t
eq_div_i_z(empq_t q, eint_t a, empz_t b)
{
    empz_set_i(mpq_numref(q), a);
    mpz_set(mpq_denref(q), b);
    mpq_canonicalize(q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_div_i_q(empq_t q, eint_t a, empq_t b)
{
    if (q == b) {
	empq_set_i(thr_q0, a);
	empq_div(q, thr_q0, b);
    }
    else {
	empq_set_i(q, a);
	empq_div(q, q, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_div_z_i(empq_t q, empz_t a, eint_t b)
{
    check_int_divide_by_zero(b);
    mpz_set(mpq_numref(q), a);
    empz_set_i(mpq_denref(q), b);
    mpq_canonicalize(q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_div_z_z(empq_t q, empz_t a, empz_t b)
{
    check_int_divide_by_zero(b);
    mpz_set(mpq_numref(q), a);
    mpz_set(mpq_denref(q), b);
    mpq_canonicalize(q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_div_z_q(empq_t q, empz_t a, empq_t b)
{
    if (q == b) {
	mpq_set_z(thr_q0, a);
	empq_div(q, thr_q0, b);
    }
    else {
	mpq_set_z(q, a);
	empq_div(q, q, b);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_div_q_i(empq_t q, empq_t a, eint_t b)
{
    if (q == a) {
	empq_set_i(thr_q0, b);
	empq_div(q, a, thr_q0);
    }
    else {
	empq_set_i(q, b);
	empq_div(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_div_q_z(empq_t q, empq_t a, empz_t b)
{
    if (q == a) {
	mpq_set_z(thr_q0, b);
	empq_div(q, a, thr_q0);
    }
    else {
	mpq_set_z(q, b);
	empq_div(q, a, q);
    }
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(a)) ? 1 : -1);
    return (0);
}

eint32_t
eq_div_q_q(empq_t q, empq_t a, empq_t b)
{
    empq_div(q, a, b);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

void
er_div_i_r(empr_t r, eint_t a, empr_t b)
{
    if (r == b) {
	empr_set_i(thr_rr0, a);
	er_div_r_r(r, thr_rr0, b);
    }
    else {
	empr_set_i(r, a);
	er_div_r_r(r, r, b);
    }
}

void
er_div_d_r(empr_t r, efloat_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_d(thr_rr0, a, thr_rnd);
	er_div_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_d(r, a, thr_rnd);
	er_div_r_r(r, r, b);
    }
}

void
er_div_z_r(empr_t r, empz_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_z(thr_rr0, a, thr_rnd);
	er_div_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_z(r, a, thr_rnd);
	er_div_r_r(r, r, b);
    }
}

void
er_div_q_r(empr_t r, empq_t a, empr_t b)
{
    if (r == b) {
	mpfr_set_q(thr_rr0, a, thr_rnd);
	er_div_r_r(r, thr_rr0, b);
    }
    else {
	mpfr_set_q(r, a, thr_rnd);
	er_div_r_r(r, r, b);
    }
}

void
er_div_r_i(empr_t r, empr_t a, eint_t b)
{
    if (r == a) {
	empr_set_i(thr_rr0, b);
	er_div_r_r(r, a, thr_rr0);
    }
    else {
	empr_set_i(r, b);
	er_div_r_r(r, a, r);
    }
}

void
er_div_r_d(empr_t r, empr_t a, efloat_t b)
{
    if (r == a) {
	mpfr_set_d(thr_rr0, b, thr_rnd);
	er_div_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_d(r, b, thr_rnd);
	er_div_r_r(r, a, r);
    }
}

void
er_div_r_z(empr_t r, empr_t a, empz_t b)
{
    if (r == a) {
	mpfr_set_z(thr_rr0, b, thr_rnd);
	er_div_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_z(r, b, thr_rnd);
	er_div_r_r(r, a, r);
    }
}

void
er_div_r_q(empr_t r, empr_t a, empq_t b)
{
    if (r == a) {
	mpfr_set_q(thr_rr0, b, thr_rnd);
	er_div_r_r(r, a, thr_rr0);
    }
    else {
	mpfr_set_q(r, b, thr_rnd);
	er_div_r_r(r, a, r);
    }
}

ecdd_t
edd_div_d_qq(efloat_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a / d);
}

ecdd_t
edd_div_dd_qq(ecdd_t a, ecqq_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(b));
    imag(d) = mpq_get_d(cqq_imagref(b));

    return (a / d);
}

ecdd_t
edd_div_qq_d(ecqq_t a, efloat_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d / b);
}

ecdd_t
edd_div_qq_dd(ecqq_t a, ecdd_t b)
{
    ecdd_t	d;

    real(d) = mpq_get_d(cqq_realref(a));
    imag(d) = mpq_get_d(cqq_imagref(a));

    return (d / b);
}

void
eqq_div_i_qq(ecqq_t q, eint_t a, ecqq_t b)
{
    empq_set_i(thr_q3, a);
    mpq_mul(thr_q1, cqq_imagref(b), cqq_imagref(b));
    mpq_mul(thr_q2, cqq_realref(b), cqq_realref(b));
    mpq_add(thr_q1, thr_q2, thr_q1);
    mpq_mul(cqq_imagref(q), cqq_imagref(b), thr_q3);
    mpq_neg(cqq_imagref(q), cqq_imagref(q));
    empq_div(cqq_imagref(q), cqq_imagref(q), thr_q1);
    mpq_mul(cqq_realref(q), thr_q3, cqq_realref(b));
    empq_div(cqq_realref(q), cqq_realref(q), thr_q1);
}

void
eqq_div_z_qq(ecqq_t q, empz_t a, ecqq_t b)
{
    mpq_set_z(thr_q3, a);
    mpq_mul(thr_q1, cqq_imagref(b), cqq_imagref(b));
    mpq_mul(thr_q2, cqq_realref(b), cqq_realref(b));
    mpq_add(thr_q1, thr_q2, thr_q1);
    mpq_mul(cqq_imagref(q), cqq_imagref(b), thr_q3);
    mpq_neg(cqq_imagref(q), cqq_imagref(q));
    empq_div(cqq_imagref(q), cqq_imagref(q), thr_q1);
    mpq_mul(cqq_realref(q), thr_q3, cqq_realref(b));
    empq_div(cqq_realref(q), cqq_realref(q), thr_q1);
}

void
eqq_div_q_qq(ecqq_t q, empq_t a, ecqq_t b)
{
    mpq_mul(thr_q1, cqq_imagref(b), cqq_imagref(b));
    mpq_mul(thr_q2, cqq_realref(b), cqq_realref(b));
    mpq_add(thr_q1, thr_q2, thr_q1);
    mpq_mul(cqq_imagref(q), cqq_imagref(b), a);
    mpq_neg(cqq_imagref(q), cqq_imagref(q));
    empq_div(cqq_imagref(q), cqq_imagref(q), thr_q1);
    mpq_mul(cqq_realref(q), a, cqq_realref(b));
    empq_div(cqq_realref(q), cqq_realref(q), thr_q1);
}

void
eqq_div_qq_i(ecqq_t q, ecqq_t a, eint_t b)
{
    eq_div_q_i(cqq_realref(q), cqq_realref(a), b);
    eq_div_q_i(cqq_imagref(q), cqq_imagref(a), b);
}

void
eqq_div_qq_z(ecqq_t q, ecqq_t a, empz_t b)
{
    eq_div_q_z(cqq_realref(q), cqq_realref(a), b);
    eq_div_q_z(cqq_imagref(q), cqq_imagref(a), b);
}

void
eqq_div_qq_q(ecqq_t q, ecqq_t a, empq_t b)
{
    empq_div(cqq_realref(q), cqq_realref(a), b);
    empq_div(cqq_imagref(q), cqq_imagref(a), b);
}

void
eqq_div_qq_qq(ecqq_t q, ecqq_t a, ecqq_t b)
{
    mpq_mul(thr_q2, cqq_imagref(a), cqq_realref(b));
    mpq_mul(thr_q1, cqq_imagref(b), cqq_realref(a));
    mpq_sub(thr_q2, thr_q2, thr_q1);
    mpq_mul(thr_q1, cqq_realref(a), cqq_realref(b));
    mpq_mul(thr_q0, cqq_imagref(a), cqq_imagref(b));
    mpq_add(thr_q1, thr_q1, thr_q0);
    mpq_mul(cqq_imagref(q), cqq_imagref(b), cqq_imagref(b));
    mpq_mul(cqq_realref(q), cqq_realref(b), cqq_realref(b));
    mpq_add(thr_q0, cqq_realref(q), cqq_imagref(q));
    empq_div(cqq_imagref(q), thr_q2, thr_q0);
    empq_div(cqq_realref(q), thr_q1, thr_q0);
}

void
ecc_div_i_cc(empc_t c, eint_t a, empc_t b)
{
    if (c == b) {
	empc_set_i(thr_c0, a);
	ecc_div_cc_cc(c, thr_c0, b);
    }
    else {
	empc_set_i(c, a);
	ecc_div_cc_cc(c, c, b);
    }
}

void
ecc_div_d_cc(empc_t c, efloat_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d(thr_c0, a, thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d(c, a, thr_rndc);
	ecc_div_cc_cc(c, c, b);
    }
}

void
ecc_div_z_cc(empc_t c, empz_t a, empc_t b)
{
    if (c == b) {
	mpc_set_z(thr_c0, a, thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_z(c, a, thr_rndc);
	ecc_div_cc_cc(c, c, b);
    }
}

void
ecc_div_q_cc(empc_t c, empq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q(thr_c0, a, thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q(c, a, thr_rndc);
	ecc_div_cc_cc(c, c, b);
    }
}

void
ecc_div_r_cc(empc_t c, empr_t a, empc_t b)
{
    if (c == b) {
	mpc_set_fr(thr_c0, a, thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_fr(c, a, thr_rndc);
	ecc_div_cc_cc(c, c, b);
    }
}

void
ecc_div_r_dd(empc_t c, empr_t a, ecdd_t b)
{
    mpc_set_d_d(c, real(b), imag(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
}

void
ecc_div_r_qq(empc_t c, empr_t a, ecqq_t b)
{
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
}

void
ecc_div_dd_r(empc_t c, ecdd_t a, empr_t b)
{
    mpc_set_d_d(c, real(a), imag(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_div_cc_cc(c, c, thr_c0);
}

void
ecc_div_qq_r(empc_t c, ecqq_t a, empr_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_fr(thr_c0, b, thr_rndc);
    ecc_div_cc_cc(c, c, thr_c0);
}

void
ecc_div_dd_cc(empc_t c, ecdd_t a, empc_t b)
{
    if (c == b) {
	mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_d_d(c, real(a), imag(a), thr_rndc);
	ecc_div_cc_cc(c, c, b);
    }
}

void
ecc_div_qq_cc(empc_t c, ecqq_t a, empc_t b)
{
    if (c == b) {
	mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
    }
    else {
	mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
	ecc_div_cc_cc(c, c, b);
    }
}

void
ecc_div_cc_i(empc_t c, empc_t a, eint_t b)
{
    if (c == a) {
	empc_set_i(thr_c0, b);
	ecc_div_cc_cc(c, a, thr_c0);
    }
    else {
	empc_set_i(c, b);
	ecc_div_cc_cc(c, a, c);
    }
}

void
ecc_div_cc_d(empc_t c, empc_t a, efloat_t b)
{
    if (c == a) {
	mpc_set_d(thr_c0, b, thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d(c, b, thr_rndc);
	ecc_div_cc_cc(c, a, c);
    }
}

void
ecc_div_cc_z(empc_t c, empc_t a, empz_t b)
{
    if (c == a) {
	mpc_set_z(thr_c0, b, thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_z(c, b, thr_rndc);
	ecc_div_cc_cc(c, a, c);
    }
}

void
ecc_div_cc_q(empc_t c, empc_t a, empq_t b)
{
    if (c == a) {
	mpc_set_q(thr_c0, b, thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q(c, b, thr_rndc);
	ecc_div_cc_cc(c, a, c);
    }
}

void
ecc_div_cc_r(empc_t c, empc_t a, empr_t b)
{
    if (c == a) {
	mpc_set_fr(thr_c0, b, thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_fr(c, b, thr_rndc);
	ecc_div_cc_cc(c, a, c);
    }
}

void
ecc_div_cc_dd(empc_t c, empc_t a, ecdd_t b)
{
    if (c == a) {
	mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_d_d(c, real(b), imag(b), thr_rndc);
	ecc_div_cc_cc(c, a, c);
    }
}

void
ecc_div_cc_qq(empc_t c, empc_t a, ecqq_t b)
{
    if (c == a) {
	mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
    }
    else {
	mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_div_cc_cc(c, a, c);
    }
}

eint32_t
ez_trunc_i_z(empz_t z, eint_t a, empz_t b)
{
    if (z == b) {
	empz_set_i(thr_z0, a);
	mpz_tdiv_q(z, thr_z0, b);
    }
    else {
	empz_set_i(z, a);
	mpz_tdiv_q(z, z, b);
    }
    return (empz_fit_i(z));
}

eint_t
ez_trunc_i_q(empz_t z, eint_t a, empq_t b)
{
    if (emp_ui_p(a))
	mpz_mul_ui(z, mpq_denref(b), a);
    else {
	empz_set_i(z, a);
	mpz_mul(z, z, mpq_denref(b));
    }
    mpz_tdiv_q(z, z, mpq_numref(b));
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_i_r(empz_t z, eint_t a, empr_t b)
{
    if (emp_ui_p(a))
	mpfr_ui_div(thr_rr0, a, b, thr_rnd);
    else {
	empr_set_i(thr_rr0, a);
	er_div_r_r(thr_rr0, thr_rr0, b);
    }
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_d(empz_t z, efloat_t a)
{
    efloat_t	d;

    modf(a, &d);
    if (d == (eint_t)d)
	return (d);
    mpz_set_d(z, d);
    if (empz_fit_i(z))
	return (empz_get_i(z));
    return (MININT);
}

eint_t
ez_trunc_d_r(empz_t z, efloat_t a, empr_t b)
{
    mpfr_set_d(thr_rr0, a, thr_rnd);
    er_div_r_r(thr_rr0, thr_rr0, b);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_z_i(empz_t z, empz_t a, eint_t b)
{
    if (unlikely(b == 0))
	ethread_kill(SIGFPE);
    if (emp_ui_p(b))
	mpz_tdiv_q_ui(z, a, b);
    else if (z == a) {
	empz_set_i(thr_z0, b);
	mpz_tdiv_q(z, a, thr_z0);
    }
    else {
	empz_set_i(z, b);
	mpz_tdiv_q(z, a, z);
    }
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_trunc_z_z(empz_t z, empz_t a, empz_t b)
{
    mpz_tdiv_q(z, a, b);
    return (empz_fit_i(z));
}

eint_t
ez_trunc_z_q(empz_t z, empz_t a, empq_t b)
{
    mpz_mul(z, a, mpq_denref(b));
    mpz_tdiv_q(z, z, mpq_numref(b));
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_z_r(empz_t z, empz_t a, empr_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    er_div_r_r(thr_rr0, thr_rr0, b);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_q_i(empz_t z, empq_t a, eint_t b)
{
    if (unlikely(b == 0))
	ethread_kill(SIGFPE);
    if (emp_ui_p(b))
	mpz_mul_ui(z, mpq_denref(a), b);
    else {
	empz_set_i(z, b);
	mpz_mul(z, mpq_denref(a), z);
    }
    mpz_tdiv_q(z, mpq_numref(a), z);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_trunc_q_z(empz_t z, empq_t a, empz_t b)
{
    mpz_mul(z, mpq_denref(a), b);
    mpz_tdiv_q(z, mpq_numref(a), z);
    return (empz_fit_i(z));
}

eint_t
ez_trunc_q_q(empz_t z, empq_t a, empq_t b)
{
    empq_div(thr_q0, a, b);
    mpz_tdiv_q(z, mpq_numref(thr_q0), mpq_denref(thr_q0));
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_q_r(empz_t z, empq_t a, empr_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    er_div_r_r(thr_rr0, thr_rr0, b);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_r_i(empz_t z, empr_t a, eint_t b)
{
    empr_set_i(thr_rr0, b);
    er_div_r_r(thr_rr0, a, thr_rr0);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_r_d(empz_t z, empr_t a, efloat_t b)
{
    mpfr_set_d(thr_ri0, b, thr_rnd);
    er_div_r_r(thr_rr0, a, thr_ri0);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_trunc_r_z(empz_t z, empr_t a, empz_t b)
{
    mpfr_set_z(thr_ri0, b, thr_rnd);
    er_div_r_r(thr_rr0, a, thr_ri0);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z));
}

eint_t
ez_trunc_r_q(empz_t z, empr_t a, empq_t b)
{
    mpfr_set_q(thr_ri0, b, thr_rnd);
    er_div_r_r(thr_rr0, a, thr_ri0);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint_t
ez_trunc_r_r(empz_t z, empr_t a, empr_t b)
{
    er_div_r_r(thr_rr0, a, b);
    mpfr_trunc(thr_rr0, thr_rr0);
    empz_set_r(z, thr_rr0);
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_rem_i_z(empz_t z, eint_t a, empz_t b)
{
    if (z == b) {
	empz_set_i(thr_z0, a);
	mpz_tdiv_r(z, thr_z0, b);
    }
    else {
	empz_set_i(z, a);
	mpz_tdiv_r(z, z, b);
    }
    return (empz_fit_i(z));
}

eint_t
ez_rem_z_i(empz_t z, empz_t a, eint_t b)
{
    check_int_divide_by_zero(b);
    if (emp_ui_p(b) && mpz_sgn(a) > 0)
	return (mpz_tdiv_ui(a, b));
    if (z == a) {
	empz_set_i(thr_z0, b);
	mpz_tdiv_r(z, a, thr_z0);
    }
    else {
	empz_set_i(z, b);
	mpz_tdiv_r(z, a, z);
    }
    return (empz_fit_i(z) ? empz_get_i(z) : MININT);
}

eint32_t
ez_rem_z_z(empz_t z, empz_t a, empz_t b)
{
    mpz_tdiv_r(z, a, b);
    return (empz_fit_i(z));
}

eint32_t
eq_rem_i_q(empq_t q, eint_t a, empq_t b)
{
    if (q == b) {
	if (emp_ui_p(a))
	    mpz_mul_ui(mpq_denref(q), mpq_denref(q), a);
	else {
	    empz_set_i(thr_z0, a);
	    mpz_mul(mpq_denref(q), mpq_denref(q), thr_z0);
	}
	mpz_tdiv_r(mpq_numref(q), mpq_denref(q), mpq_numref(q));
    }
    else {
	if (emp_ui_p(a))
	    mpz_mul_ui(thr_z0, mpq_denref(b), a);
	else {
	    empz_set_i(thr_z0, a);
	    mpz_mul(thr_z0, thr_z0, mpq_denref(b));
	}
	mpz_tdiv_r(mpq_numref(q), thr_z0, mpq_numref(b));
	mpz_set(mpq_denref(q), mpq_denref(b));
    }
    mpq_canonicalize(q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_rem_z_q(empq_t q, empz_t a, empq_t b)
{
    if (q == b) {
	mpz_mul(mpq_denref(q), a, mpq_denref(q));
	mpz_tdiv_r(mpq_numref(q), mpq_denref(q), mpq_numref(q));
    }
    else {
	mpz_mul(thr_z0, a, mpq_denref(b));
	mpz_tdiv_r(mpq_numref(q), thr_z0, mpq_numref(b));
	mpz_set(mpq_denref(q), mpq_denref(b));
    }
    mpq_canonicalize(q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_rem_q_i(empq_t q, empq_t a, eint_t b)
{
    check_int_divide_by_zero(b);
    if (emp_ui_p(b))
	mpz_mul_ui(thr_z0, mpq_denref(a), b);
    else {
	empz_set_i(thr_z0, b);
	mpz_mul(thr_z0, mpq_denref(a), thr_z0);
    }
    mpz_tdiv_r(mpq_numref(q), mpq_numref(a), thr_z0);
    if (q != a)
	mpz_set(mpq_denref(q), mpq_denref(a));
    mpq_canonicalize(q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_rem_q_z(empq_t q, empq_t a, empz_t b)
{
    mpz_mul(thr_z0, mpq_denref(a), b);
    mpz_tdiv_r(mpq_numref(q), mpq_numref(a), thr_z0);
    if (q != a)
	mpz_set(mpq_denref(q), mpq_denref(a));
    mpq_canonicalize(q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_rem_q_q(empq_t q, empq_t a, empq_t b)
{
    if (q == a || q == b) {
	mpz_mul(thr_z0, mpq_denref(a), mpq_denref(b));
	empq_div(q, a, b);
	mpz_tdiv_r(mpq_numref(q), mpq_numref(q), mpq_denref(q));
	mpz_set(mpq_denref(q), thr_z0);
    }
    else {
	empq_div(q, a, b);
	mpz_tdiv_r(mpq_numref(q), mpq_numref(q), mpq_denref(q));
	mpz_mul(mpq_denref(q), mpq_denref(a), mpq_denref(b));
    }
    mpq_canonicalize(q);
    if (mpq_sgn(b) < 0)
	mpq_neg(q, q);
    if (!mpz_cmp_ui(mpq_denref(q), 1))
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

void
er_rem_i_r(empr_t r, eint_t a, empr_t b)
{
    empr_set_i(r, a);
    mpfr_fmod(r, r, b, thr_rnd);
}

void
er_rem_d_r(empr_t r, efloat_t a, empr_t b)
{
    mpfr_set_d(r, a, thr_rnd);
    mpfr_fmod(r, r, b, thr_rnd);
}

void
er_rem_z_r(empr_t r, empz_t a, empr_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    mpfr_fmod(r, r, b, thr_rnd);
}

void
er_rem_q_r(empr_t r, empq_t a, empr_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    mpfr_fmod(r, r, b, thr_rnd);
}

void
er_rem_r_i(empr_t r, empr_t a, eint_t b)
{
    empr_set_i(r, b);
    mpfr_fmod(r, a, r, thr_rnd);
}

void
er_rem_r_d(empr_t r, empr_t a, efloat_t b)
{
    mpfr_set_d(r, b, thr_rnd);
    mpfr_fmod(r, a, r, thr_rnd);
}

void
er_rem_r_z(empr_t r, empr_t a, empz_t b)
{
    mpfr_set_z(r, b, thr_rnd);
    mpfr_fmod(r, a, r, thr_rnd);
}

void
er_rem_r_q(empr_t r, empr_t a, empq_t b)
{
    mpfr_set_q(r, b, thr_rnd);
    mpfr_fmod(r, a, r, thr_rnd);
}

void
er_atan2_i_i(empr_t r, eint_t a, eint_t b)
{
    empr_set_i(r, a);
    empr_set_i(thr_rr0, b);
    er_atan2_r_r(r, r, thr_rr0);
}

void
er_atan2_i_z(empr_t r, eint_t a, empz_t b)
{
    empr_set_i(r, a);
    mpfr_set_z(thr_rr0, b, thr_rnd);
    er_atan2_r_r(r, r, thr_rr0);
}

void
er_atan2_i_q(empr_t r, eint_t a, empq_t b)
{
    empr_set_i(r, a);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    er_atan2_r_r(r, r, thr_rr0);
}

void
er_atan2_i_r(empr_t r, eint_t a, empr_t b)
{
    if (a) {
	empr_set_i(thr_rr0, a);
	er_atan2_r_r(r, thr_rr0, b);
    }
    else if (likely(!mpfr_nan_p(b))) {
	if (mpfr_sgn(b) >= 0)
	    mpfr_set_ui(r, 0, thr_rnd);
	else
	    mpfr_const_pi(r, thr_rnd);
    }
    else
	mpfr_set_nan(r);
}

void
er_atan2_d_r(empr_t r, efloat_t a, empr_t b)
{
    if (a != 0.0) {
	mpfr_set_d(thr_rr0, a, thr_rnd);
	er_atan2_r_r(r, thr_rr0, b);
    }
    else if (likely(!mpfr_nan_p(b))) {
	if (mpfr_sgn(b) >= 0)
	    mpfr_set_ui(r, 0, thr_rnd);
	else
	    mpfr_const_pi(r, thr_rnd);
    }
    else
	mpfr_set_nan(r);
}

void
er_atan2_z_i(empr_t r, empz_t a, eint_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    empr_set_i(r, b);
    er_atan2_r_r(r, thr_rr0, r);
}

void
er_atan2_z_z(empr_t r, empz_t a, empz_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    mpfr_set_z(r, b, thr_rnd);
    er_atan2_r_r(r, thr_rr0, r);
}

void
er_atan2_z_q(empr_t r, empz_t a, empq_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    mpfr_set_q(r, b, thr_rnd);
    er_atan2_r_r(r, thr_rr0, r);
}

void
er_atan2_z_r(empr_t r, empz_t a, empr_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    er_atan2_r_r(r, thr_rr0, b);
}

void
er_atan2_q_i(empr_t r, empq_t a, eint_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    empr_set_i(r, b);
    er_atan2_r_r(r, thr_rr0, r);
}

void
er_atan2_q_z(empr_t r, empq_t a, empz_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    mpfr_set_z(r, b, thr_rnd);
    er_atan2_r_r(r, thr_rr0, r);
}

void
er_atan2_q_q(empr_t r, empq_t a, empq_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    mpfr_set_q(r, b, thr_rnd);
    er_atan2_r_r(r, thr_rr0, r);
}

void
er_atan2_q_r(empr_t r, empq_t a, empr_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    er_atan2_r_r(r, thr_rr0, b);
}

void
er_atan2_r_i(empr_t r, empr_t a, eint_t b)
{
    empr_set_i(thr_rr0, b);
    er_atan2_r_r(r, a, thr_rr0);
}

void
er_atan2_r_d(empr_t r, empr_t a, efloat_t b)
{
    mpfr_set_d(thr_rr0, b, thr_rnd);
    er_atan2_r_r(r, a, thr_rr0);
}

void
er_atan2_r_z(empr_t r, empr_t a, empz_t b)
{
    mpfr_set_z(thr_rr0, b, thr_rnd);
    er_atan2_r_r(r, a, thr_rr0);
}

void
er_atan2_r_q(empr_t r, empr_t a, empq_t b)
{
    mpfr_set_q(thr_rr0, b, thr_rnd);
    er_atan2_r_r(r, a, thr_rr0);
}

ecdd_t
edd_atan2_i_dd(eint_t a, ecdd_t b)
{
    ecdd_t	dd;
    if (a) {
	real(dd) = a;
	imag(dd) = 0.0;
	return (catan(dd / b));
    }
    real(dd) = real(b) >= 0.0 ? 0.0 : M_PI;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_d_dd(efloat_t a, ecdd_t b)
{
    ecdd_t	dd;
    if (a != 0.0) {
	real(dd) = a;
	imag(dd) = 0.0;
	return (catan(dd / b));
    }
    real(dd) = real(b) >= 0.0 ? 0.0 : M_PI;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_z_dd(empz_t a, ecdd_t b)
{
    ecdd_t	dd;
    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;
    return (catan(dd / b));
}

ecdd_t
edd_atan2_q_dd(empq_t a, ecdd_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;
    return (catan(dd / b));
}

ecdd_t
edd_atan2_i_qq(eint_t a, ecqq_t b)
{
    ecdd_t	dd;
    if (a) {
	ecdd_t	ee;
	real(dd) = a;
	imag(dd) = 0.0;
	real(ee) = mpq_get_d(cqq_realref(b));
	imag(ee) = mpq_get_d(cqq_imagref(b));
	return (catan(dd / ee));
    }
    real(dd) = mpq_sgn(cqq_realref(b)) >= 0 ? 0.0 : M_PI;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_d_qq(efloat_t a, ecqq_t b)
{
    ecdd_t	dd;
    if (a != 0.0) {
	ecdd_t	ee;
	real(dd) = a;
	imag(dd) = 0.0;
	real(ee) = mpq_get_d(cqq_realref(b));
	imag(ee) = mpq_get_d(cqq_imagref(b));
	return (catan(dd / ee));
    }
    real(dd) = mpq_sgn(cqq_realref(b)) >= 0 ? 0.0 : M_PI;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_z_qq(empz_t a, ecqq_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(cqq_realref(b));
    imag(dd) = mpq_get_d(cqq_imagref(b));
    return (catan(mpz_get_d(a) / dd));
}

ecdd_t
edd_atan2_q_qq(empq_t a, ecqq_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(cqq_realref(b));
    imag(dd) = mpq_get_d(cqq_imagref(b));
    return (catan(mpq_get_d(a) / dd));
}

void
ecc_atan2_r_cc(empc_t c, empr_t a, empc_t b)
{
    if (!mpfr_zero_p(a)) {
	mpc_set_fr(thr_c0, a, thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
	mpc_atan(c, c, thr_rndc);
    }
    else {
	if (mpfr_sgn(mpc_realref(b)) >= 0)
	    mpc_set_ui(c, 0, thr_rndc);
	else {
	    mpfr_const_pi(mpc_realref(c), thr_rnd);
	    mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
	}
    }
}

ecdd_t
edd_atan2_dd_i(ecdd_t a, eint_t b)
{
    ecdd_t	dd;
    if (b) {
	real(dd) = b;
	imag(dd) = 0;
	return (catan(a / dd));
    }
    real(dd) = real(a) >= 0.0 ? M_PI_2 : -M_PI_2;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_dd_d(ecdd_t a, efloat_t b)
{
    ecdd_t	dd;
    if (b != 0.0) {
	real(dd) = b;
	imag(dd) = 0;
	return (catan(a / dd));
    }
    real(dd) = real(a) >= 0.0 ? M_PI_2 : -M_PI_2;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_dd_z(ecdd_t a, empz_t b)
{
    ecdd_t	dd;
    real(dd) = mpz_get_d(b);
    imag(dd) = 0.0;
    return (catan(a / dd));
}

ecdd_t
edd_atan2_dd_q(ecdd_t a, empq_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(b);
    imag(dd) = 0.0;
    return (catan(a / dd));
}

ecdd_t
edd_atan2_dd_qq(ecdd_t a, ecqq_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(cqq_realref(b));
    imag(dd) = mpq_get_d(cqq_imagref(b));
    return (catan(a / dd));
}

ecdd_t
edd_atan2_qq_i(ecqq_t a, eint_t b)
{
    ecdd_t	dd;
    if (b) {
	ecdd_t	ee;
	real(dd) = mpq_get_d(cqq_realref(a));
	imag(dd) = mpq_get_d(cqq_imagref(a));
	real(ee) = b;
	imag(ee) = 0.0;
	return (catan(dd / ee));
    }
    real(dd) = mpq_sgn(cqq_realref(a)) >= 0 ? M_PI_2 : -M_PI_2;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_qq_d(ecqq_t a, efloat_t b)
{
    ecdd_t	dd;
    if (b != 0.0) {
	ecdd_t	ee;
	real(dd) = mpq_get_d(cqq_realref(a));
	imag(dd) = mpq_get_d(cqq_imagref(a));
	real(ee) = b;
	imag(ee) = 0.0;
	return (catan(dd / ee));
    }
    real(dd) = mpq_sgn(cqq_realref(a)) >= 0 ? M_PI_2 : -M_PI_2;
    imag(dd) = 0.0;
    return (dd);
}

ecdd_t
edd_atan2_qq_z(ecqq_t a, empz_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));
    return (catan(dd / mpz_get_d(b)));
}

ecdd_t
edd_atan2_qq_q(ecqq_t a, empq_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));
    return (catan(dd / mpq_get_d(b)));
}

ecdd_t
edd_atan2_qq_dd(ecqq_t a, ecdd_t b)
{
    ecdd_t	dd;
    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));
    return (catan(dd / b));
}

ecdd_t
edd_atan2_qq_qq(ecqq_t a, ecqq_t b)
{
    ecdd_t	dd;
    ecdd_t	ee;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));
    real(ee) = mpq_get_d(cqq_realref(b));
    imag(ee) = mpq_get_d(cqq_imagref(b));

    return (catan(dd / ee));
}

void
ecc_atan2_i_qq(empc_t c, eint_t a, ecqq_t b)
{
    if (a) {
	empc_set_i(thr_c0, a);
	mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_div_cc_cc(c, thr_c0, c);
	mpc_atan(c, c, thr_rndc);
    }
    else if (mpq_sgn(cqq_realref(b)) >= 0)
	mpc_set_ui(c, 0, thr_rndc);
    else {
	mpfr_const_pi(mpc_realref(c), thr_rnd);
	mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
    }
}

void
ecc_atan2_i_cc(empc_t c, eint_t a, empc_t b)
{
    if (a) {
	empc_set_i(thr_c0, a);
	ecc_div_cc_cc(c, thr_c0, b);
	mpc_atan(c, c, thr_rndc);
    }
    else if (mpfr_sgn(mpc_realref(b)) >= 0)
	mpc_set_ui(c, 0, thr_rndc);
    else {
	mpfr_const_pi(mpc_realref(c), thr_rnd);
	mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
    }
}

void
ecc_atan2_d_cc(empc_t c, efloat_t a, empc_t b)
{
    if (a != 0.0) {
	mpc_set_d(thr_c0, a, thr_rndc);
	ecc_div_cc_cc(c, thr_c0, b);
	mpc_atan(c, c, thr_rndc);
    }
    else if (mpfr_sgn(mpc_realref(b)) >= 0)
	mpc_set_ui(c, 0, thr_rndc);
    else {
	mpfr_const_pi(mpc_realref(c), thr_rnd);
	mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
    }
}

void
ecc_atan2_z_qq(empc_t c, empz_t a, ecqq_t b)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_z_cc(empc_t c, empz_t a, empc_t b)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    ecc_div_cc_cc(c, thr_c0, b);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_q_qq(empc_t c, empq_t a, ecqq_t b)
{
    mpc_set_q(thr_c0, a, thr_rndc);
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_q_cc(empc_t c, empq_t a, empc_t b)
{
    mpc_set_q(thr_c0, a, thr_rndc);
    ecc_div_cc_cc(c, thr_c0, b);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_r_dd(empc_t c, empr_t a, ecdd_t b)
{
    if (mpfr_zero_p(a)) {
	if (real(b) >= 0)
	    mpc_set_ui(c, 0, thr_rndc);
	else {
	    mpfr_const_pi(mpc_realref(c), thr_rnd);
	    mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
	}
    }
    else {
	mpc_set_fr(c, a, thr_rndc);
	mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
	ecc_div_cc_cc(c, c, thr_c0);
	mpc_atan(c, c, thr_rndc);
    }
}

void
ecc_atan2_r_qq(empc_t c, empr_t a, ecqq_t b)
{
    if (mpfr_zero_p(a)) {
	if (mpq_sgn(cqq_realref(b)) >= 0)
	    mpc_set_ui(c, 0, thr_rndc);
	else {
	    mpfr_const_pi(mpc_realref(c), thr_rnd);
	    mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
	}
    }
    else {
	mpc_set_fr(c, a, thr_rndc);
	mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
	ecc_div_cc_cc(c, c, thr_c0);
	mpc_atan(c, c, thr_rndc);
    }
}

void
ecc_atan2_dd_r(empc_t c, ecdd_t a, empr_t b)
{
    mpc_set_fr(c, b, thr_rndc);
    mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_dd_cc(empc_t c, ecdd_t a, empc_t b)
{
    mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
    ecc_div_cc_cc(c, thr_c0, b);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_qq_i(empc_t c, ecqq_t a, eint_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    empc_set_i(c, b);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_qq_z(empc_t c, ecqq_t a, empz_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_z(c, b, thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_qq_q(empc_t c, ecqq_t a, empq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_q(c, b, thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_qq_r(empc_t c, ecqq_t a, empr_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_fr(c, b, thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_qq_qq(empc_t c, ecqq_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    ecc_div_cc_cc(c, thr_c0, c);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_qq_cc(empc_t c, ecqq_t a, empc_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_div_cc_cc(c, thr_c0, b);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_cc_i(empc_t c, empc_t a, eint_t b)
{
    if (b) {
	empc_set_i(thr_c0, b);
	ecc_div_cc_cc(c, a, thr_c0);
	mpc_atan(c, c, thr_rndc);
    }
    else {
	ebool_t	neg = mpfr_sgn(mpc_realref(a)) < 0;
	mpfr_const_pi(mpc_realref(c), thr_rnd);
	mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
	mpfr_div_2exp(mpc_realref(c), mpc_realref(c), 1, thr_rnd);
	if (neg)
	    mpfr_neg(mpc_realref(c), mpc_realref(c), thr_rnd);
    }
}

void
ecc_atan2_cc_d(empc_t c, empc_t a, efloat_t b)
{
    if (b != 0.0) {
	mpc_set_d(thr_c0, b, thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
	mpc_atan(c, c, thr_rndc);
    }
    else {
	ebool_t	neg = mpfr_sgn(mpc_realref(a)) < 0;
	mpfr_const_pi(mpc_realref(c), thr_rnd);
	mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
	mpfr_div_2exp(mpc_realref(c), mpc_realref(c), 1, thr_rnd);
	if (neg)
	    mpfr_neg(mpc_realref(c), mpc_realref(c), thr_rnd);
    }
}

void
ecc_atan2_cc_z(empc_t c, empc_t a, empz_t b)
{
    mpc_set_z(thr_c0, b, thr_rndc);
    ecc_div_cc_cc(c, a, thr_c0);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_cc_q(empc_t c, empc_t a, empq_t b)
{
    mpc_set_q(thr_c0, b, thr_rndc);
    ecc_div_cc_cc(c, a, thr_c0);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_cc_r(empc_t c, empc_t a, empr_t b)
{
    if (!mpfr_zero_p(b)) {
	mpc_set_fr(thr_c0, b, thr_rndc);
	ecc_div_cc_cc(c, a, thr_c0);
	mpc_atan(c, c, thr_rndc);
    }
    else {
	ebool_t	neg = mpfr_sgn(mpc_realref(a)) < 0;
	mpfr_const_pi(mpc_realref(c), thr_rnd);
	mpfr_set_ui(mpc_imagref(c), 0, thr_rnd);
	mpfr_div_2exp(mpc_realref(c), mpc_realref(c), 1, thr_rnd);
	if (neg)
	    mpfr_neg(mpc_realref(c), mpc_realref(c), thr_rnd);
    }
}

void
ecc_atan2_cc_dd(empc_t c, empc_t a, ecdd_t b)
{
    mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
    ecc_div_cc_cc(c, a, thr_c0);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_cc_qq(empc_t c, empc_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    ecc_div_cc_cc(c, a, thr_c0);
    mpc_atan(c, c, thr_rndc);
}

void
ecc_atan2_cc_cc(empc_t c, empc_t a, empc_t b)
{
    ecc_div_cc_cc(c, a, b);
    mpc_atan(c, c, thr_rndc);
}

void
er_pow_i_i(empr_t r, eint_t a, eint_t b)
{
    empr_set_i(thr_rr0, a);
    empr_set_i(thr_ri0, b);
    mpfr_pow(r, thr_rr0, thr_ri0, thr_rnd);
}

void
er_pow_i_z(empr_t r, eint_t a, empz_t b)
{
    empr_set_i(thr_rr0, a);
    mpfr_set_z(thr_ri0, b, thr_rnd);
    mpfr_pow(r, thr_rr0, thr_ri0, thr_rnd);
}

void
er_pow_i_q(empr_t r, eint_t a, empq_t b)
{
    empr_set_i(thr_rr0, a);
    mpfr_set_q(thr_ri0, b, thr_rnd);
    mpfr_pow(r, thr_rr0, thr_ri0, thr_rnd);
}

void
er_pow_i_r(empr_t r, eint_t a, empr_t b)
{
    empr_set_i(thr_rr0, a);
    mpfr_pow(r, thr_rr0, b, thr_rnd);
}

void
er_pow_d_r(empr_t r, efloat_t a, empr_t b)
{
    mpfr_set_d(thr_rr0, a, thr_rnd);
    mpfr_pow(r, thr_rr0, b, thr_rnd);
}

void
er_pow_z_i(empr_t r, empz_t a, eint_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    empr_set_i(thr_rr0, b);
    mpfr_pow(r, r, thr_rr0, thr_rnd);
}

void
er_pow_z_z(empr_t r, empz_t a, empz_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_pow(r, r, thr_rr0, thr_rnd);
}

void
er_pow_z_q(empr_t r, empz_t a, empq_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_pow(r, r, thr_rr0, thr_rnd);
}

void
er_pow_z_r(empr_t r, empz_t a, empr_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    mpfr_pow(r, thr_rr0, b, thr_rnd);
}

void
er_pow_q_i(empr_t r, empq_t a, eint_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    empr_set_i(thr_rr0, b);
    mpfr_pow(r, r, thr_rr0, thr_rnd);
}

void
er_pow_q_z(empr_t r, empq_t a, empz_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_pow(r, r, thr_rr0, thr_rnd);
}

void
er_pow_q_q(empr_t r, empq_t a, empq_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_pow(r, r, thr_rr0, thr_rnd);
}

void
er_pow_q_r(empr_t r, empq_t a, empr_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    mpfr_pow(r, thr_rr0, b, thr_rnd);
}

void
er_pow_r_i(empr_t r, empr_t a, eint_t b)
{
    empr_set_i(thr_rr0, b);
    mpfr_pow(r, a, thr_rr0, thr_rnd);
}

void
er_pow_r_d(empr_t r, empr_t a, efloat_t b)
{
    mpfr_set_d(thr_rr0, b, thr_rnd);
    mpfr_pow(r, a, thr_rr0, thr_rnd);
}

void
er_pow_r_z(empr_t r, empr_t a, empz_t b)
{
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_pow(r, a, thr_rr0, thr_rnd);
}

void
er_pow_r_q(empr_t r, empr_t a, empq_t b)
{
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_pow(r, a, thr_rr0, thr_rnd);
}

ecdd_t
edd_pow_i_d(eint_t a, efloat_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = a;
    imag(da) = 0.0;
    real(db) = b;
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_i_q(eint_t a, empq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = a;
    imag(da) = 0.0;
    real(db) = mpq_get_d(b);
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_i_dd(eint_t a, ecdd_t b)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (cpow(dd, b));
}

ecdd_t
edd_pow_i_qq(eint_t a, ecqq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = a;
    imag(da) = 0.0;
    real(db) = mpq_get_d(cqq_realref(b));
    imag(db) = mpq_get_d(cqq_imagref(b));

    return (cpow(da, db));
}

ecdd_t
edd_pow_d_i(efloat_t a, eint_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = a;
    imag(da) = 0.0;
    real(db) = b;
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_d_d(efloat_t a, efloat_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = a;
    imag(da) = 0.0;
    real(db) = b;
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_d_q(efloat_t a, empq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = a;
    imag(da) = 0.0;
    real(db) = mpq_get_d(b);
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_d_dd(efloat_t a, ecdd_t b)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (cpow(dd, b));
}

ecdd_t
edd_pow_d_qq(efloat_t a, ecqq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = a;
    imag(da) = 0.0;
    real(db) = mpq_get_d(cqq_realref(b));
    imag(db) = mpq_get_d(cqq_imagref(b));

    return (cpow(da, db));
}

ecdd_t
edd_pow_z_d(empz_t a, efloat_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpz_get_d(a);
    imag(da) = 0.0;
    real(db) = b;
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_z_q(empz_t a, empq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpz_get_d(a);
    imag(da) = 0.0;
    real(db) = mpq_get_d(b);
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_z_dd(empz_t a, ecdd_t b)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (cpow(dd, b));
}

ecdd_t
edd_pow_z_qq(empz_t a, ecqq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpz_get_d(a);
    imag(da) = 0.0;
    real(db) = mpq_get_d(cqq_realref(b));
    imag(db) = mpq_get_d(cqq_imagref(b));

    return (cpow(da, db));
}

ecdd_t
edd_pow_q_d(empq_t a, efloat_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(a);
    imag(da) = 0.0;
    real(db) = b;
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_q_q(empq_t a, empq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(a);
    imag(da) = 0.0;
    real(db) = mpq_get_d(b);
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_q_dd(empq_t a, ecdd_t b)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (cpow(dd, b));
}

ecdd_t
edd_pow_q_qq(empq_t a, ecqq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(a);
    imag(da) = 0.0;
    real(db) = mpq_get_d(cqq_realref(b));
    imag(db) = mpq_get_d(cqq_imagref(b));

    return (cpow(da, db));
}

ecdd_t
edd_pow_dd_i(ecdd_t a, eint_t b)
{
    ecdd_t	dd;

    real(dd) = b;
    imag(dd) = 0.0;

    return (cpow(a, dd));
}

ecdd_t
edd_pow_dd_d(ecdd_t a, efloat_t b)
{
    ecdd_t	dd;

    real(dd) = b;
    imag(dd) = 0.0;

    return (cpow(a, dd));
}

ecdd_t
edd_pow_dd_z(ecdd_t a, empz_t b)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(b);
    imag(dd) = 0.0;

    return (cpow(a, dd));
}

ecdd_t
edd_pow_dd_q(ecdd_t a, empq_t b)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(b);
    imag(dd) = 0.0;

    return (cpow(a, dd));
}

ecdd_t
edd_pow_dd_qq(ecdd_t a, ecqq_t b)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(b));
    imag(dd) = mpq_get_d(cqq_imagref(b));

    return (cpow(a, dd));
}

ecdd_t
edd_pow_qq_i(ecqq_t a, eint_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(cqq_realref(a));
    imag(da) = mpq_get_d(cqq_imagref(a));
    real(db) = b;
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_qq_d(ecqq_t a, efloat_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(cqq_realref(a));
    imag(da) = mpq_get_d(cqq_imagref(a));
    real(db) = b;
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_qq_z(ecqq_t a, empz_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(cqq_realref(a));
    imag(da) = mpq_get_d(cqq_imagref(a));
    real(db) = mpz_get_d(b);
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_qq_q(ecqq_t a, empq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(cqq_realref(a));
    imag(da) = mpq_get_d(cqq_imagref(a));
    real(db) = mpq_get_d(b);
    imag(db) = 0.0;

    return (cpow(da, db));
}

ecdd_t
edd_pow_qq_dd(ecqq_t a, ecdd_t b)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (cpow(dd, b));
}

ecdd_t
edd_pow_qq_qq(ecqq_t a, ecqq_t b)
{
    ecdd_t	da;
    ecdd_t	db;

    real(da) = mpq_get_d(cqq_realref(a));
    imag(da) = mpq_get_d(cqq_imagref(a));
    real(db) = mpq_get_d(cqq_realref(b));
    imag(db) = mpq_get_d(cqq_imagref(b));

    return (cpow(da, db));
}

void
ecc_pow_i_r(empc_t c, eint_t a, empr_t b)
{
    empc_set_i(thr_c0, a);
    mpc_pow_fr(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_i_q(empc_t c, eint_t a, empq_t b)
{
    empc_set_i(c, a);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_i_qq(empc_t c, eint_t a, ecqq_t b)
{
    empc_set_i(thr_c0, a);
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_pow(c, thr_c0, c, thr_rndc);
}

void
ecc_pow_i_cc(empc_t c, eint_t a, empc_t b)
{
    empc_set_i(thr_c0, a);
    mpc_pow(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_d_r(empc_t c, efloat_t a, empr_t b)
{
    mpc_set_d(thr_c0, a, thr_rndc);
    mpc_pow_fr(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_d_cc(empc_t c, efloat_t a, empc_t b)
{
    mpc_set_d(thr_c0, a, thr_rndc);
    mpc_pow(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_z_q(empc_t c, empz_t a, empq_t b)
{
    mpc_set_z(c, a, thr_rndc);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_z_r(empc_t c, empz_t a, empr_t b)
{
    mpc_set_z(c, a, thr_rndc);
    mpc_pow_fr(c, c, b, thr_rndc);
}

void
ecc_pow_z_qq(empc_t c, empz_t a, ecqq_t b)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_pow(c, thr_c0, c, thr_rndc);
}

void
ecc_pow_z_cc(empc_t c, empz_t a, empc_t b)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    mpc_pow(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_q_r(empc_t c, empq_t a, empr_t b)
{
    mpc_set_q(c, a, thr_rndc);
    mpc_pow_fr(c, c, b, thr_rndc);
}

void
ecc_pow_q_q(empc_t c, empq_t a, empq_t b)
{
    mpc_set_q(c, a, thr_rndc);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_q_qq(empc_t c, empq_t a, ecqq_t b)
{
    mpc_set_q(thr_c0, a, thr_rndc);
    mpc_set_q_q(c, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_pow(c, thr_c0, c, thr_rndc);
}

void
ecc_pow_q_cc(empc_t c, empq_t a, empc_t b)
{
    mpc_set_q(thr_c0, a, thr_rnd);
    mpc_pow(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_r_d(empc_t c, empr_t a, efloat_t b)
{
    mpc_set_fr(c, a, thr_rndc);
    mpfr_set_d(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_r_q(empc_t c, empr_t a, empq_t b)
{
    mpc_set_fr(c, a, thr_rndc);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_r_r(empc_t c, empr_t a, empr_t b)
{
    mpc_set_fr(thr_c0, a, thr_rndc);
    mpc_pow_fr(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_r_dd(empc_t c, empr_t a, ecdd_t b)
{
    mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
    mpc_set_fr(c, a, thr_rndc);
    mpc_pow(c, c, thr_c0, thr_rndc);
}

void
ecc_pow_r_qq(empc_t c, empr_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_set_fr(c, a, thr_rndc);
    mpc_pow(c, c, thr_c0, thr_rndc);
}

void
ecc_pow_r_cc(empc_t c, empr_t a, empc_t b)
{
    mpc_set_fr(thr_c0, a, thr_rndc);
    mpc_pow(c, thr_c0, b, thr_rndc);
}


void
ecc_pow_dd_r(empc_t c, ecdd_t a, empr_t b)
{
    mpc_set_d_d(c, real(a), imag(a), thr_rndc);
    mpc_pow_fr(c, c, b, thr_rndc);
}

void
ecc_pow_dd_cc(empc_t c, ecdd_t a, empc_t b)
{
    mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
    mpc_pow(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_qq_i(empc_t c, ecqq_t a, eint_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    empr_set_i(thr_rr0, b);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_qq_z(empc_t c, ecqq_t a, empz_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_qq_q(empc_t c, ecqq_t a, empq_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, c, thr_rr0, thr_rndc);
}

void
ecc_pow_qq_r(empc_t c, ecqq_t a, empr_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_pow_fr(c, c, b, thr_rndc);
}

void
ecc_pow_qq_qq(empc_t c, ecqq_t a, ecqq_t b)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_pow(c, c, thr_c0, thr_rndc);
}

void
ecc_pow_qq_cc(empc_t c, ecqq_t a, empc_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_pow(c, thr_c0, b, thr_rndc);
}

void
ecc_pow_cc_i(empc_t c, empc_t a, eint_t b)
{
    empr_set_i(thr_rr0, b);
    mpc_pow_fr(c, a, thr_rr0, thr_rndc);
}

void
ecc_pow_cc_d(empc_t c, empc_t a, efloat_t b)
{
    mpfr_set_d(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, a, thr_rr0, thr_rndc);
}

void
ecc_pow_cc_z(empc_t c, empc_t a, empz_t b)
{
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, a, thr_rr0, thr_rndc);
}

void
ecc_pow_cc_q(empc_t c, empc_t a, empq_t b)
{
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpc_pow_fr(c, a, thr_rr0, thr_rndc);
}

void
ecc_pow_cc_dd(empc_t c, empc_t a, ecdd_t b)
{
    mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
    mpc_pow(c, a, thr_c0, thr_rndc);
}

void
ecc_pow_cc_qq(empc_t c, empc_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpc_pow(c, a, thr_c0, thr_rndc);
}

efloat_t
ed_hypot_i_dd(eint_t a, ecdd_t b)
{
    return (hypot(a, hypot(real(b), imag(b))));
}

efloat_t
ed_hypot_i_qq(eint_t a, ecqq_t b)
{
    return (hypot(a, hypot(mpq_get_d(cqq_realref(b)),
			   mpq_get_d(cqq_imagref(b)))));
}

efloat_t
ed_hypot_d_dd(efloat_t a, ecdd_t b)
{
    return (hypot(a, hypot(real(b), imag(b))));
}

efloat_t
ed_hypot_d_qq(efloat_t a, ecqq_t b)
{
    return (hypot(a, hypot(mpq_get_d(cqq_realref(b)),
			   mpq_get_d(cqq_imagref(b)))));
}

efloat_t
ed_hypot_z_dd(empz_t a, ecdd_t b)
{
    return (hypot(mpz_get_d(a), hypot(real(b), imag(b))));
}

efloat_t
ed_hypot_z_qq(empz_t a, ecqq_t b)
{
    return (hypot(mpz_get_d(a), hypot(mpq_get_d(cqq_realref(b)),
				      mpq_get_d(cqq_imagref(b)))));
}

efloat_t
ed_hypot_q_dd(empq_t a, ecdd_t b)
{
    return (hypot(mpq_get_d(a), hypot(real(b), imag(b))));
}

efloat_t
ed_hypot_q_qq(empq_t a, ecqq_t b)
{
    return (hypot(mpq_get_d(a), hypot(mpq_get_d(cqq_realref(b)),
				      mpq_get_d(cqq_imagref(b)))));
}

efloat_t
ed_hypot_dd_i(ecdd_t a, eint_t b)
{
    return (hypot(hypot(real(a), imag(a)), b));
}

efloat_t
ed_hypot_dd_d(ecdd_t a, efloat_t b)
{
    return (hypot(hypot(real(a), imag(a)), b));
}

efloat_t
ed_hypot_dd_z(ecdd_t a, empz_t b)
{
    return (hypot(hypot(real(a), imag(a)), mpz_get_d(b)));
}

efloat_t
ed_hypot_dd_q(ecdd_t a, empq_t b)
{
    return (hypot(hypot(real(a), imag(a)), mpq_get_d(b)));
}

efloat_t
ed_hypot_dd_dd(ecdd_t a, ecdd_t b)
{
    return (hypot(hypot(real(a), imag(a)), hypot(real(b), imag(b))));
}

efloat_t
ed_hypot_dd_qq(ecdd_t a, ecqq_t b)
{
    return (hypot(hypot(real(a), imag(a)),
		  hypot(mpq_get_d(cqq_realref(b)), mpq_get_d(cqq_imagref(b)))));
}

efloat_t
ed_hypot_qq_i(ecqq_t a, eint_t b)
{
    return (hypot(hypot(mpq_get_d(cqq_realref(a)),
			mpq_get_d(cqq_imagref(a))), b));
}

efloat_t
ed_hypot_qq_d(ecqq_t a, efloat_t b)
{
    return (hypot(hypot(mpq_get_d(cqq_realref(a)),
			mpq_get_d(cqq_imagref(a))), b));
}

efloat_t
ed_hypot_qq_z(ecqq_t a, empz_t b)
{
    return (hypot(hypot(mpq_get_d(cqq_realref(a)),
			mpq_get_d(cqq_imagref(a))), mpz_get_d(b)));
}

efloat_t
ed_hypot_qq_q(ecqq_t a, empq_t b)
{
    return (hypot(hypot(mpq_get_d(cqq_realref(a)),
			mpq_get_d(cqq_imagref(a))), mpq_get_d(b)));
}

efloat_t
ed_hypot_qq_dd(ecqq_t a, ecdd_t b)
{
    return (hypot(hypot(mpq_get_d(cqq_realref(a)),
			mpq_get_d(cqq_imagref(a))), hypot(real(b), imag(b))));
}

efloat_t
ed_hypot_qq_qq(ecqq_t a, ecqq_t b)
{
    return (hypot(hypot(mpq_get_d(cqq_realref(a)),
			mpq_get_d(cqq_imagref(a))),
		  hypot(mpq_get_d(cqq_realref(b)),
			mpq_get_d(cqq_imagref(b)))));
}

void
er_hypot_i_i(empr_t r, eint_t a, eint_t b)
{
    empr_set_i(r, a);
    empr_set_i(thr_rr0, b);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_i_z(empr_t r, eint_t a, empz_t b)
{
    empr_set_i(r, a);
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_i_q(empr_t r, eint_t a, empq_t b)
{
    empr_set_i(r, a);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_i_r(empr_t r, eint_t a, empr_t b)
{
    empr_set_i(thr_rr0, a);
    mpfr_hypot(r, thr_rr0, b, thr_rnd);
}

void
er_hypot_i_qq(empr_t r, eint_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    empr_set_i(r, a);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_i_cc(empr_t r, eint_t a, empc_t b)
{
    empr_set_i(thr_rr0, a);
    mpfr_hypot(r, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_d_r(empr_t r, efloat_t a, empr_t b)
{
    mpfr_set_d(thr_rr0, a, thr_rnd);
    mpfr_hypot(r, thr_rr0, b, thr_rnd);
}

void
er_hypot_d_cc(empr_t r, efloat_t a, empc_t b)
{
    mpfr_set_d(thr_rr0, a, thr_rnd);
    mpfr_hypot(r, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_z_i(empr_t r, empz_t a, eint_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    empr_set_i(thr_rr0, b);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_z_z(empr_t r, empz_t a, empz_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_z_q(empr_t r, empz_t a, empq_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_z_r(empr_t r, empz_t a, empr_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    mpfr_hypot(r, thr_rr0, b, thr_rnd);
}

void
er_hypot_z_qq(empr_t r, empz_t a, ecqq_t b)
{
    mpfr_set_z(r, a, thr_rnd);
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_z_cc(empr_t r, empz_t a, empc_t b)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    mpfr_hypot(r, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_q_i(empr_t r, empq_t a, eint_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    empr_set_i(thr_rr0, b);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_q_z(empr_t r, empq_t a, empz_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_q_q(empr_t r, empq_t a, empq_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_q_r(empr_t r, empq_t a, empr_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    mpfr_hypot(r, thr_rr0, b, thr_rnd);
}

void
er_hypot_q_qq(empr_t r, empq_t a, ecqq_t b)
{
    mpfr_set_q(r, a, thr_rnd);
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_q_cc(empr_t r, empq_t a, empc_t b)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    mpfr_hypot(r, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_r_i(empr_t r, empr_t a, eint_t b)
{
    empr_set_i(thr_rr0, b);
    mpfr_hypot(r, a, thr_rr0, thr_rnd);
}

void
er_hypot_r_d(empr_t r, empr_t a, efloat_t b)
{
    mpfr_set_d(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, a, thr_rr0, thr_rnd);
}

void
er_hypot_r_z(empr_t r, empr_t a, empz_t b)
{
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, a, thr_rr0, thr_rnd);
}

void
er_hypot_r_q(empr_t r, empr_t a, empq_t b)
{
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, a, thr_rr0, thr_rnd);
}

void
er_hypot_r_dd(empr_t r, empr_t a, ecdd_t b)
{
    mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, a, thr_rr0, thr_rnd);
}

void
er_hypot_r_qq(empr_t r, empr_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, a, thr_rr0, thr_rnd);
}

void
er_hypot_r_cc(empr_t r, empr_t a, empc_t b)
{
    mpfr_hypot(thr_rr0, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, a, thr_rr0, thr_rnd);
}

void
er_hypot_dd_r(empr_t r, ecdd_t a, empr_t b)
{
    mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, thr_rr0, b, thr_rnd);
}

void
er_hypot_dd_cc(empr_t r, ecdd_t a, empc_t b)
{
    mpc_set_d_d(thr_c0, real(a), imag(a), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_qq_i(empr_t r, ecqq_t a, eint_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    empr_set_i(r, b);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_qq_z(empr_t r, ecqq_t a, empz_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_set_z(r, b, thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_qq_q(empr_t r, ecqq_t a, empq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_set_q(r, b, thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_qq_r(empr_t r, ecqq_t a, empr_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, thr_rr0, b, thr_rnd);
}

void
er_hypot_qq_qq(empr_t r, ecqq_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_hypot(r, thr_rr0, thr_ri0, thr_rnd);
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_qq_cc(empr_t r, ecqq_t a, empc_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

void
er_hypot_cc_i(empr_t r, empc_t a, eint_t b)
{
    empr_set_i(thr_rr0, b);
    mpfr_hypot(r, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_cc_d(empr_t r, empc_t a, efloat_t b)
{
    mpfr_set_d(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_cc_z(empr_t r, empc_t a, empz_t b)
{
    mpfr_set_z(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_cc_q(empr_t r, empc_t a, empq_t b)
{
    mpfr_set_q(thr_rr0, b, thr_rnd);
    mpfr_hypot(r, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_cc_r(empr_t r, empc_t a, empr_t b)
{
    mpfr_hypot(thr_rr0, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(r, thr_rr0, b, thr_rnd);
}

void
er_hypot_cc_dd(empr_t r, empc_t a, ecdd_t b)
{
    mpc_set_d_d(thr_c0, real(b), imag(b), thr_rndc);
    mpfr_hypot(r, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_cc_qq(empr_t r, empc_t a, ecqq_t b)
{
    mpc_set_q_q(thr_c0, cqq_realref(b), cqq_imagref(b), thr_rndc);
    mpfr_hypot(r, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(thr_rr0, thr_rr0, thr_ri0, thr_rnd);
    mpfr_hypot(r, r, thr_rr0, thr_rnd);
}

void
er_hypot_cc_cc(empr_t r, empc_t a, empc_t b)
{
    mpfr_hypot(thr_rr0, mpc_realref(a), mpc_imagref(a), thr_rnd);
    mpfr_hypot(r, mpc_realref(b), mpc_imagref(b), thr_rnd);
    mpfr_hypot(r, thr_rr0, r, thr_rnd);
}

efloat_t
ed_signum_d(efloat_t a)
{
    if (likely(!isnan(a)))
	return (a ? a > 0.0 ? 1.0 : -1.0 : 0.0);
    return (NAN);
}

void
er_signum_r(empr_t r, empr_t a)
{
    if (likely(!mpfr_nan_p(a)))
	mpfr_set_si(r, mpfr_sgn(a), thr_rnd);
    else
	mpfr_set_nan(r);
}

ecdd_t
edd_signum_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_signum_dd(dd));
}

void
ecc_signum_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    /* note: should always be a safe usage of thr_ri (but worth a note...)
     * i.e. only special case should be: c == thr_c */
    mpfr_hypot(thr_ri, thr_rr0, thr_ri0, thr_rnd);
    er_div_r_r(mpc_realref(c), thr_rr0, thr_ri);
    er_div_r_r(mpc_imagref(c), thr_ri0, thr_ri);
}

void
ecc_signum_cc(empc_t c, empc_t a)
{
    mpfr_hypot(thr_rr0, mpc_realref(a), mpc_imagref(a), thr_rnd);
    er_div_r_r(mpc_realref(c), mpc_realref(a), thr_rr0);
    er_div_r_r(mpc_imagref(c), mpc_imagref(a), thr_rr0);
}

eint32_t
eq_rational_d(empq_t q, efloat_t a)
{
    mpq_set_d(q, a);
    if (mpz_cmp_ui(mpq_denref(q), 1) == 0)
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

eint32_t
eq_rational_r(empq_t q, empr_t a)
{
    mpfr_get_f(thr_f0, a, thr_rnd);
    mpq_set_f(q, thr_f0);
    if (mpz_cmp_ui(mpq_denref(q), 1) == 0)
	return (empz_fit_i(mpq_numref(q)) ? 1 : -1);
    return (0);
}

void
eqq_conj_qq(ecqq_t qq, ecqq_t a)
{
    mpq_neg(cqq_imagref(qq), cqq_imagref(a));
    if (qq != a)
	mpq_set(cqq_realref(qq), cqq_realref(a));
}

void
ecc_conj_cc(empc_t c, empc_t a)
{
    mpfr_neg(mpc_imagref(c), mpc_imagref(a), thr_rnd);
    if (c != a)
	empr_set(mpc_realref(c), mpc_realref(a));
}

efloat_t
ed_arg_d(efloat_t a)
{
    if (likely(!isnan(a)))
	return (a >= 0.0 ? 0.0 : M_PI);
    return (NAN);
}

efloat_t
ed_arg_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (carg(dd));
}

void
er_arg_i(empr_t r, eint_t a)
{
    if (a >= 0)
	mpfr_set_ui(r, 0, thr_rnd);
    else
	mpfr_const_pi(r, thr_rnd);
}

void
er_arg_z(empr_t r, empz_t a)
{
    if (mpz_sgn(a) >= 0)
	mpfr_set_ui(r, 0, thr_rnd);
    else
	mpfr_const_pi(r, thr_rnd);
}

void
er_arg_q(empr_t r, empq_t a)
{
    if (mpq_sgn(a) >= 0)
	mpfr_set_ui(r, 0, thr_rnd);
    else
	mpfr_const_pi(r, thr_rnd);
}

void
er_arg_r(empr_t r, empr_t a)
{
    if (likely(!mpfr_nan_p(a))) {
	if (mpfr_sgn(a) >= 0)
	    mpfr_set_ui(r, 0, thr_rnd);
	else
	    mpfr_const_pi(r, thr_rnd);
    }
    else
	mpfr_set_nan(r);
}

void
er_arg_qq(empr_t r, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    er_arg_cc(r, thr_c0);
}

eint_t
ez_abs_i(empz_t z, eint_t a)
{
    if (likely(a != MININT))
	return (a >= 0 ? a : -a);
    empz_set_u(z, MININT);

    return (MININT);
}

efloat_t
ed_abs_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (cabs(dd));
}

void
er_abs_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_abs_r(r, r);
}

void
er_abs_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_abs_r(r, r);
}

void
er_abs_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_abs_r(r, r);
}

void
er_abs_qq(empr_t r, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    er_abs_cc(r, thr_c0);
}

void
er_sqrt_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_sqrt_r(r, r);
}

void
er_sqrt_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_sqrt_r(r, r);
}

void
er_sqrt_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_sqrt_r(r, r);
}

ecdd_t
edd_sqrt_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0;

    return (edd_sqrt_dd(dd));
}

ecdd_t
edd_sqrt_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0;

    return (edd_sqrt_dd(dd));
}

ecdd_t
edd_sqrt_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0;

    return (edd_sqrt_dd(dd));
}

ecdd_t
edd_sqrt_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0;

    return (edd_sqrt_dd(dd));
}

ecdd_t
edd_sqrt_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_sqrt_dd(dd));
}

void
ecc_sqrt_i(empc_t c, eint_t a)
{
    empc_set_i(c, a);
    ecc_sqrt_cc(c, c);
}

void
ecc_sqrt_z(empc_t c, empz_t a)
{
    mpc_set_z(c, a, thr_rndc);
    ecc_sqrt_cc(c, c);
}

void
ecc_sqrt_q(empc_t c, empq_t a)
{
    mpc_set_q(c, a, thr_rndc);
    ecc_sqrt_cc(c, c);
}

void
ecc_sqrt_r(empc_t c, empr_t a)
{
    mpc_set_fr(c, a, thr_rndc);
    ecc_sqrt_cc(c, c);
}

void
ecc_sqrt_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_sqrt_cc(c, c);
}

void
er_cbrt_i(empr_t r, eint_t a)
{
    empr_set_i(thr_rr0, a);
    er_cbrt_r(r, thr_rr0);
}

void
er_cbrt_z(empr_t r, empz_t a)
{
    mpfr_set_z(thr_rr0, a, thr_rnd);
    er_cbrt_r(r, thr_rr0);
}

void
er_cbrt_q(empr_t r, empq_t a)
{
    mpfr_set_q(thr_rr0, a, thr_rnd);
    er_cbrt_r(r, thr_rr0);
}

ecdd_t
edd_cbrt_dd(ecdd_t a)
{
#if 0
    r0.v.cdd = cpow(r0.v.cdd, 1.0 / 3.0);
#else
    /* this "should" be more accurate */
#  if !HAVE_SINCOS
    efloat_t	f;
#  endif
    efloat_t	d;
    ecdd_t	dd;

    d = exp(log(cabs(a)) / 3.0);
#  if HAVE_SINCOS
    sincos(atan2(imag(a), real(a)) / 3.0, &imag(dd), &real(dd));
#  else
    f = atan2(imag(a), real(a)) / 3.0;
    imag(dd) = sin(f);
    real(dd) = cos(f);
#  endif
    real(dd) *= d;
    imag(dd) *= d;

    return (dd);
#endif
}

ecdd_t
edd_cbrt_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_cbrt_dd(dd));
}

void
ecc_cbrt_qq(empc_t c, ecqq_t a)
{
    mpc_set_ui_ui(thr_c0, 1, 3, thr_rndc);
    /* note: should always be a safe usage of thr_rr (but worth a note...)
     * i.e. only special case should be: c == thr_c */
    er_div_r_r(thr_rr, thr_rr0, thr_ri0);
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    mpc_pow_fr(c, thr_c0, thr_rr, thr_rndc);
}

void
ecc_cbrt_cc(empc_t c, empc_t a)
{
    mpc_set_ui_ui(thr_c0, 1, 3, thr_rndc);
    er_div_r_r(thr_rr0, thr_rr0, thr_ri0);
    mpc_pow_fr(c, a, thr_rr0, thr_rndc);
}

void
er_sin_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_sin_r(r, r);
}

void
er_sin_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_sin_r(r, r);
}

void
er_sin_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_sin_r(r, r);
}

ecdd_t
edd_sin_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_sin_dd(dd));
}

void
ecc_sin_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_sin_cc(c, thr_c0);
}

void
er_cos_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_cos_r(r, r);
}

void
er_cos_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_cos_r(r, r);
}

void
er_cos_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_cos_r(r, r);
}

ecdd_t
edd_cos_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_cos_dd(dd));
}

void
ecc_cos_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_cos_cc(c, thr_c0);
}

void
er_tan_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_tan_r(r, r);
}

void
er_tan_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_tan_r(r, r);
}

void
er_tan_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_tan_r(r, r);
}

ecdd_t
edd_tan_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_tan_dd(dd));
}

void
ecc_tan_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_tan_cc(c, thr_c0);
}

void
er_asin_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_asin_r(r, r);
}

void
er_asin_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_asin_r(r, r);
}

void
er_asin_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_asin_r(r, r);
}

ecdd_t
edd_asin_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_asin_dd(dd));
}

ecdd_t
edd_asin_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_asin_dd(dd));
}

ecdd_t
edd_asin_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (edd_asin_dd(dd));
}

ecdd_t
edd_asin_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (edd_asin_dd(dd));
}

ecdd_t
edd_asin_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (casin(dd));
}

void
ecc_asin_i(empc_t c, eint_t a)
{
    empc_set_i(thr_c0, a);
    ecc_asin_cc(c, thr_c0);
}

void
ecc_asin_z(empc_t c, empz_t a)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    ecc_asin_cc(c, thr_c0);
}

void
ecc_asin_q(empc_t c, empq_t a)
{
    mpc_set_q(thr_c0, a, thr_rndc);
    ecc_asin_cc(c, thr_c0);
}

void
ecc_asin_r(empc_t c, empr_t a)
{
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_asin_cc(c, thr_c0);
}

void
ecc_asin_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_asin_cc(c, thr_c0);
}

void
er_acos_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_acos_r(r, r);
}

void
er_acos_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_acos_r(r, r);
}

void
er_acos_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_acos_r(r, r);
}

ecdd_t
edd_acos_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_acos_dd(dd));
}

ecdd_t
edd_acos_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_acos_dd(dd));
}

ecdd_t
edd_acos_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (edd_acos_dd(dd));
}

ecdd_t
edd_acos_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (edd_acos_dd(dd));
}

ecdd_t
edd_acos_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_acos_dd(dd));
}

void
ecc_acos_i(empc_t c, eint_t a)
{
    empc_set_i(thr_c0, a);
    ecc_acos_cc(c, thr_c0);
}

void
ecc_acos_z(empc_t c, empz_t a)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    ecc_acos_cc(c, thr_c0);
}

void
ecc_acos_q(empc_t c, empq_t a)
{
    mpc_set_q(thr_c0, a, thr_rndc);
    ecc_acos_cc(c, thr_c0);
}

void
ecc_acos_r(empc_t c, empr_t a)
{
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_acos_cc(c, thr_c0);
}

void
ecc_acos_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_acos_cc(c, thr_c0);
}

void
er_atan_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_atan_r(r, r);
}

void
er_atan_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_atan_r(r, r);
}

void
er_atan_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_atan_r(r, r);
}

ecdd_t
edd_atan_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_atan_dd(dd));
}

void
ecc_atan_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_atan_cc(c, thr_c0);
}

void
er_sinh_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_sinh_r(r, r);
}

void
er_sinh_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_sinh_r(r, r);
}

void
er_sinh_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_sinh_r(r, r);
}

ecdd_t
edd_sinh_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_sinh_dd(dd));
}

void
ecc_sinh_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_sinh_cc(c, thr_c0);
}

void
er_cosh_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_cosh_r(r, r);
}

void
er_cosh_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_cosh_r(r, r);
}

void
er_cosh_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_cosh_r(r, r);
}

ecdd_t
edd_cosh_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_cosh_dd(dd));
}

void
ecc_cosh_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_cosh_cc(c, thr_c0);
}

void
er_tanh_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_tanh_r(r, r);
}

void
er_tanh_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_tanh_r(r, r);
}

void
er_tanh_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_tanh_r(r, r);
}

ecdd_t
edd_tanh_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_tanh_dd(dd));
}

void
ecc_tanh_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_tanh_cc(c, thr_c0);
}

void
er_asinh_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_asinh_r(r, r);
}

void
er_asinh_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_asinh_r(r, r);
}

void
er_asinh_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_asinh_r(r, r);
}

ecdd_t
edd_asinh_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_asinh_dd(dd));
}

void
ecc_asinh_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_asinh_cc(c, thr_c0);
}

void
er_acosh_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_acosh_r(r, r);
}

void
er_acosh_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_acosh_r(r, r);
}

void
er_acosh_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_acosh_r(r, r);
}

ecdd_t
edd_acosh_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_acosh_dd(dd));
}

ecdd_t
edd_acosh_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_acosh_dd(dd));
}

ecdd_t
edd_acosh_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (edd_acosh_dd(dd));
}

ecdd_t
edd_acosh_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (edd_acosh_dd(dd));
}

ecdd_t
edd_acosh_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_acosh_dd(dd));
}

void
ecc_acosh_i(empc_t c, eint_t a)
{
    empc_set_i(thr_c0, a);
    ecc_acosh_cc(c, thr_c0);
}

void
ecc_acosh_z(empc_t c, empz_t a)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    ecc_acosh_cc(c, thr_c0);
}

void
ecc_acosh_q(empc_t c, empq_t a)
{
    mpc_set_q(thr_c0, a, thr_rndc);
    ecc_acosh_cc(c, thr_c0);
}

void
ecc_acosh_r(empc_t c, empr_t a)
{
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_acosh_cc(c, thr_c0);
}

void
ecc_acosh_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_acosh_cc(c, thr_c0);
}

void
er_atanh_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_atanh_r(r, r);
}

void
er_atanh_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_atanh_r(r, r);
}

void
er_atanh_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_atanh_r(r, r);
}

ecdd_t
edd_atanh_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_atanh_dd(dd));
}

ecdd_t
edd_atanh_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (edd_atanh_dd(dd));
}

ecdd_t
edd_atanh_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (edd_atanh_dd(dd));
}

ecdd_t
edd_atanh_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (edd_atanh_dd(dd));
}

ecdd_t
edd_atanh_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_atanh_dd(dd));
}

void
ecc_atanh_i(empc_t c, eint_t a)
{
    empc_set_i(thr_c0, a);
    ecc_atanh_cc(c, thr_c0);
}

void
ecc_atanh_z(empc_t c, empz_t a)
{
    mpc_set_z(thr_c0, a, thr_rndc);
    ecc_atanh_cc(c, thr_c0);
}

void
ecc_atanh_q(empc_t c, empq_t a)
{
    mpc_set_q(thr_c0, a, thr_rndc);
    ecc_atanh_cc(c, thr_c0);
}

void
ecc_atanh_r(empc_t c, empr_t a)
{
    mpc_set_fr(thr_c0, a, thr_rndc);
    ecc_atanh_cc(c, thr_c0);
}

void
ecc_atanh_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_atanh_cc(c, thr_c0);
}

void
er_exp_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_exp_r(r, r);
}

void
er_exp_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_exp_r(r, r);
}

void
er_exp_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_exp_r(r, r);
}

ecdd_t
edd_exp_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (edd_exp_dd(dd));
}

void
ecc_exp_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(thr_c0, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_exp_cc(c, thr_c0);
}

efloat_t
ed_proj_d(efloat_t a)
{
    return (!isinf(a) || a > 0.0 ? a : INFINITY);
}

void
er_proj_r(empr_t r, empr_t a)
{
    if (!mpfr_inf_p(a) || mpfr_sgn(a) >= 0)
	empr_set(r, a);
    else
	mpfr_set_inf(r, 1);
}

void
er_log_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_log_r(r, r);
}

void
er_log_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_log_r(r, r);
}

void
er_log_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_log_r(r, r);
}

ecdd_t
edd_log_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (clog(dd));
}

ecdd_t
edd_log_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (clog(dd));
}

ecdd_t
edd_log_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (clog(dd));
}

ecdd_t
edd_log_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (clog(dd));
}

ecdd_t
edd_log_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (clog(dd));
}

void
ecc_log_i(empc_t c, eint_t a)
{
    empc_set_i(c, a);
    ecc_log_cc(c, c);
}

void
ecc_log_z(empc_t c, empz_t a)
{
    mpc_set_z(c, a, thr_rndc);
    ecc_log_cc(c, c);
}

void
ecc_log_q(empc_t c, empq_t a)
{
    mpc_set_q(c, a, thr_rndc);
    ecc_log_cc(c, c);
}

void
ecc_log_r(empc_t c, empr_t a)
{
    mpc_set_fr(c, a, thr_rndc);
    ecc_log_cc(c, c);
}

void
ecc_log_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_log_cc(c, c);
}

void
er_log2_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_log2_r(r, r);
}

void
er_log2_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_log2_r(r, r);
}

void
er_log2_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_log2_r(r, r);
}

ecdd_t
edd_log2_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (clog2(dd));
}

ecdd_t
edd_log2_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (clog2(dd));
}

ecdd_t
edd_log2_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (clog2(dd));
}

ecdd_t
edd_log2_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (clog2(dd));
}

ecdd_t
edd_log2_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (clog2(dd));
}

void
ecc_log2_i(empc_t c, eint_t a)
{
    empc_set_i(c, a);
    ecc_log2_cc(c, c);
}

void
ecc_log2_z(empc_t c, empz_t a)
{
    mpc_set_z(c, a, thr_rndc);
    ecc_log2_cc(c, c);
}

void
ecc_log2_q(empc_t c, empq_t a)
{
    mpc_set_q(c, a, thr_rndc);
    ecc_log2_cc(c, c);
}

void
ecc_log2_r(empc_t c, empr_t a)
{
    mpc_set_fr(c, a, thr_rndc);
    ecc_log2_cc(c, c);
}

void
ecc_log2_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_log2_cc(c, c);
}

void
ecc_log2_cc(empc_t c, empc_t a)
{
    /*
     *	v = hypot(r	i)
     *	log2(v)		1/log(2)*atan2(i, r)
     */

    /* t = hypot(r+i)							*/
    er_hypot_r_r(thr_rr0, mpc_realref(a), mpc_imagref(a));

    /* i = atan2(i, r)							*/
    er_atan2_r_r(mpc_imagref(c), mpc_imagref(a), mpc_realref(a));

    /* r = log2(t)							*/
    er_log2_r(mpc_realref(c), thr_rr0);

    /* t = 1/log(2)							*/
    	/* t = log(2)							*/
    mpfr_const_log2(thr_rr0, thr_rnd);
    	/* t1 = 1							*/
    mpfr_set_ui(thr_ri0, 1, thr_rnd);
    	/* t = t1/t							*/
    er_div_r_r(thr_rr0, thr_ri0, thr_rr0);

    /* i = t*i								*/
    er_mul_r_r(mpc_imagref(c), thr_rr0, mpc_imagref(c));
}

void
er_log10_i(empr_t r, eint_t a)
{
    empr_set_i(r, a);
    er_log10_r(r, r);
}

void
er_log10_z(empr_t r, empz_t a)
{
    mpfr_set_z(r, a, thr_rnd);
    er_log10_r(r, r);
}

void
er_log10_q(empr_t r, empq_t a)
{
    mpfr_set_q(r, a, thr_rnd);
    er_log10_r(r, r);
}

ecdd_t
edd_log10_i(eint_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (clog10(dd));
}

ecdd_t
edd_log10_d(efloat_t a)
{
    ecdd_t	dd;

    real(dd) = a;
    imag(dd) = 0.0;

    return (clog10(dd));
}

ecdd_t
edd_log10_z(empz_t a)
{
    ecdd_t	dd;

    real(dd) = mpz_get_d(a);
    imag(dd) = 0.0;

    return (clog10(dd));
}

ecdd_t
edd_log10_q(empq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(a);
    imag(dd) = 0.0;

    return (clog10(dd));
}

ecdd_t
edd_log10_qq(ecqq_t a)
{
    ecdd_t	dd;

    real(dd) = mpq_get_d(cqq_realref(a));
    imag(dd) = mpq_get_d(cqq_imagref(a));

    return (clog10(dd));
}

void
ecc_log10_i(empc_t c, eint_t a)
{
    empc_set_i(c, a);
    ecc_log10_cc(c, c);
}

void
ecc_log10_z(empc_t c, empz_t a)
{
    mpc_set_z(c, a, thr_rndc);
    ecc_log10_cc(c, c);
}

void
ecc_log10_q(empc_t c, empq_t a)
{
    mpc_set_q(c, a, thr_rndc);
    ecc_log10_cc(c, c);
}

void
ecc_log10_r(empc_t c, empr_t a)
{
    mpc_set_fr(c, a, thr_rndc);
    ecc_log10_cc(c, c);
}

void
ecc_log10_qq(empc_t c, ecqq_t a)
{
    mpc_set_q_q(c, cqq_realref(a), cqq_imagref(a), thr_rndc);
    ecc_log10_cc(c, c);
}

void
ecc_log10_cc(empc_t c, empc_t a)
{
    /*
     *	v = hypot(r	i)
     *	log10(v)	1/log(10)*atan2(i, r)
     */

    /* t = hypot(r+i)							*/
    er_hypot_r_r(thr_rr0, mpc_realref(a), mpc_imagref(a));

    /* i = atan2(i, r)							*/
    er_atan2_r_r(mpc_imagref(c), mpc_imagref(a), mpc_realref(a));

    /* r = log10(t)							*/
    er_log10_r(mpc_realref(c), thr_rr0);

    /* t = 1/log(10)							*/
    	/* t = 10							*/
    mpfr_set_ui(thr_rr0, 10, thr_rnd);
    	/* t = log(t)							*/
    er_log_r(thr_rr0, thr_rr0);
    	/* t1 = 1							*/
    mpfr_set_ui(thr_ri0, 1, thr_rnd);
    	/* t = t1/t							*/
    er_div_r_r(thr_rr0, thr_ri0, thr_rr0);

    /* i = t*i								*/
    er_mul_r_r(mpc_imagref(c), thr_rr0, mpc_imagref(c));
}
